ARMAsmParser.cpp revision eb0caa115491019f7f7fe45fc70ad47682244187
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// The LLVM Compiler Infrastructure 4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source 6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details. 7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===// 9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 10ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "ARM.h" 1192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling#include "ARMAddressingModes.h" 127597212abced110723f2fee985a7d60557c092ecEvan Cheng#include "ARMMCExpr.h" 13b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h" 143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h" 15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 16c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 17c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 186469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 19642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 21ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 22ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h" 26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 27fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2875ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 31345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 34ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#define GET_SUBTARGETINFO_ENUM 35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "ARMGenSubtargetInfo.inc" 36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser { 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 4532869205052430f45d598fba25ab878d8b29da2dEvan Cheng /// STI, ARM_STI, Thumb_STI - Subtarget info for ARM and Thumb modes. STI 4632869205052430f45d598fba25ab878d8b29da2dEvan Cheng /// points to either ARM_STI or Thumb_STI depending on the mode. 4732869205052430f45d598fba25ab878d8b29da2dEvan Cheng const MCSubtargetInfo *STI; 4832869205052430f45d598fba25ab878d8b29da2dEvan Cheng OwningPtr<const MCSubtargetInfo> ARM_STI; 4932869205052430f45d598fba25ab878d8b29da2dEvan Cheng OwningPtr<const MCSubtargetInfo> Thumb_STI; 50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 52ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 53ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 54ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 55ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 56ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 57e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int TryParseRegister(); 58bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 5950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 6150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 62ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &, 63ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode); 64fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 657597212abced110723f2fee985a7d60557c092ecEvan Cheng bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); 669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *ApplyPrefixToExpr(const MCExpr *E, 679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 69a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 76762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 77762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E); 780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool ParseShift(enum ARM_AM::ShiftOpc &St, 790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E); 80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 81515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 82515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 83515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 84515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 85515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 867036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner bool MatchAndEmitInstruction(SMLoc IDLoc, 877c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 88fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out); 89fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 90fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 9116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 92ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 93ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 94ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng return (STI->getFeatureBits() & ARM::ModeThumb) != 0; 95ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 96ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 97ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng return isThumb() && (STI->getFeatureBits() & ARM::FeatureThumb2) == 0; 98ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 9932869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 10032869205052430f45d598fba25ab878d8b29da2dEvan Cheng STI = isThumb() ? ARM_STI.get() : Thumb_STI.get(); 10132869205052430f45d598fba25ab878d8b29da2dEvan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI->getFeatureBits())); 10232869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 103ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 104a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1070692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1080692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 109a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 110a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 111a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 112f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseCoprocNumOperand( 113f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 114f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseCoprocRegOperand( 115f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 116f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseMemBarrierOptOperand( 1178bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 118a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OperandMatchResultTy tryParseProcIFlagsOperand( 1198bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 120584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OperandMatchResultTy tryParseMSRMaskOperand( 1218bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes OperandMatchResultTy tryParseMemMode2Operand( 123ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 124ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes OperandMatchResultTy tryParseMemMode3Operand( 125ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 128ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 129ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 130ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 132ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 133ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 134ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 135ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 136f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach 137ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 138480cee5d4396a380ada6ffd03551b5700d041fe0Evan Cheng ARMAsmParser(StringRef TT, StringRef CPU, StringRef FS, MCAsmParser &_Parser) 13932869205052430f45d598fba25ab878d8b29da2dEvan Cheng : TargetAsmParser(), Parser(_Parser) { 140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 14132869205052430f45d598fba25ab878d8b29da2dEvan Cheng 14232869205052430f45d598fba25ab878d8b29da2dEvan Cheng STI = ARM_MC::createARMMCSubtargetInfo(TT, CPU, FS); 14332869205052430f45d598fba25ab878d8b29da2dEvan Cheng // FIXME: Design a better way to create two subtargets with only difference 14432869205052430f45d598fba25ab878d8b29da2dEvan Cheng // being a feature change. 14532869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (isThumb()) { 14632869205052430f45d598fba25ab878d8b29da2dEvan Cheng Thumb_STI.reset(STI); 14732869205052430f45d598fba25ab878d8b29da2dEvan Cheng assert(TT.startswith("thumb") && "Unexpected Triple string for Thumb!"); 14832869205052430f45d598fba25ab878d8b29da2dEvan Cheng Twine ARM_TT = "arm" + TT.substr(5); 14932869205052430f45d598fba25ab878d8b29da2dEvan Cheng ARM_STI.reset(ARM_MC::createARMMCSubtargetInfo(ARM_TT.str(), CPU, FS)); 15032869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 15132869205052430f45d598fba25ab878d8b29da2dEvan Cheng ARM_STI.reset(STI); 15232869205052430f45d598fba25ab878d8b29da2dEvan Cheng assert(TT.startswith("arm") && "Unexpected Triple string for ARM!"); 15332869205052430f45d598fba25ab878d8b29da2dEvan Cheng Twine Thumb_TT = "thumb" + TT.substr(3); 15432869205052430f45d598fba25ab878d8b29da2dEvan Cheng Thumb_STI.reset(ARM_MC::createARMMCSubtargetInfo(Thumb_TT.str(),CPU, FS)); 15532869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 15632869205052430f45d598fba25ab878d8b29da2dEvan Cheng 157ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 158ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI->getFeatureBits())); 159ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 160ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 16138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 1629898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 163ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 164ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 16516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 16616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1673a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1683a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 169a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 171146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1738462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 174d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 175fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 176fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 177cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 178706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 1798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 180584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 181a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 1828462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1838d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 1840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 1850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 1860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Shifter, 1878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 188a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 189a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 190762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 19124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 192a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1978462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 199706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 200706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 201706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 202706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 203fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 204fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 205fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 206fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 207a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 208a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 209a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 210a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 211584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 212584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 213584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 214584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 217a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 219a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 220a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 221a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 222a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2238155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 224cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 225cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 22616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2276a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 228a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 229ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode; 230a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2312637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar union { 2322637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar unsigned RegNum; ///< Offset register num, when OffsetIsReg. 2332637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar const MCExpr *Value; ///< Offset value, when !OffsetIsReg. 2342637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar } Offset; 235146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 2360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true 237146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true 23850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Preindexed : 1; 23950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Postindexed : 1; 24050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned OffsetIsReg : 1; 24150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Negative : 1; // only used when OffsetIsReg is true 24250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Writeback : 1; 243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy; 2470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson unsigned RegNum; 2480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } Shift; 249a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 25016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 251146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 252146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 2588462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 2598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 2608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 2628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 264d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 2688d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 2690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 2700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 27124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 2728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 273fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 274fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 275fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 276fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 280706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 281706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 282706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 283762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 284762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 289a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 290a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 2910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 2920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson case Shifter: 2930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Shift = o.Shift; 2940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 296762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 29716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3038462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 308fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 309fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 310fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 311fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 312fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 315a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 317a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3196aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3207729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3235fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3240f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3250f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 32624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3278d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 329cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 330cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 331cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 332cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 333cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 334706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 335706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 336706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 337706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 338706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 339a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 340a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 341a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 342a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 343a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 344584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 345584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 346584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 347584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 348584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3496ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @name Memory Operand Accessors 3506ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @{ 351ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode getMemAddrMode() const { 352ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return Mem.AddrMode; 353ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 3546ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemBaseRegNum() const { 3556ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.BaseRegNum; 3566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegNum() const { 3586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.RegNum; 3606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemOffset() const { 3626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(!Mem.OffsetIsReg && "Invalid access!"); 3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.Value; 3646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegShifted() const { 3666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.OffsetRegShifted; 3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemShiftAmount() const { 3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftAmount; 3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc getMemShiftType() const { 3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftType; 3766ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3776ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPreindexed() const { return Mem.Preindexed; } 3786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPostindexed() const { return Mem.Postindexed; } 3796ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; } 3806ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemNegative() const { return Mem.Negative; } 3816ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemWriteback() const { return Mem.Writeback; } 3826ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 3836ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @} 3846ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 385fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 386fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 3878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 388d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 3893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 3906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 3916b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 3926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 3936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 3946b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 3956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 3966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 3976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 3986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 3996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 4056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 406b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 4078d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 4080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 4090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 41014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 411706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 41214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 4130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool isShifter() const { return Kind == Shifter; } 414ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool isMemMode2() const { 415ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode2) 416ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 417ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 418ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) 419ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 420ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 421ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemNegative() && 422ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 423ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 424ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 425ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 426ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (!CE) return false; 427ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Value = CE->getValue(); 428ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 429ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // The offset must be in the range 0-4095 (imm12). 430ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Value > 4095 || Value < -4095) 431ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 432ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 433ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 434ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 435ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool isMemMode3() const { 436ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode3) 437ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 438ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 439ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 440ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetRegShifted()) 441ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; // No shift with offset reg allowed 442ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 443ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 444ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 445ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemNegative() && 446ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 447ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 448ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 449ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 450ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (!CE) return false; 451ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Value = CE->getValue(); 452ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 453ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // The offset must be in the range 0-255 (imm8). 454ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Value > 255 || Value < -255) 455ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 456ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 457ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 458ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 45987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling bool isMemMode5() const { 4604b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || 4614b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar getMemNegative()) 46287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 463ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 4644b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 465ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 466ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 46787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling // The offset must be a multiple of 4 in the range 0-1020. 46887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling int64_t Value = CE->getValue(); 46987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); 47087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 471505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes bool isMemMode7() const { 472505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!isMemory() || 473505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPreindexed() || 474505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPostindexed() || 475505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemOffsetIsReg() || 476505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemNegative() || 477505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemWriteback()) 478505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 479505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 480505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 481505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!CE) return false; 482505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 483505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (CE->getValue()) 484505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 485505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 486505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return true; 487505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 488f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeRegThumb() const { 4894b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback()) 490f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 491d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar return true; 492f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 493f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeImmThumb() const { 4944b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback()) 495ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 496ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 4974b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 498ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 499ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 500ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // The offset must be a multiple of 4 in the range 0-124. 501ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling uint64_t Value = CE->getValue(); 502ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return ((Value & 0x3) == 0 && Value <= 124); 503ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 504584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 505a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 5063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 5073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 50814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 50914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 51014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 51114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 5123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 5133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 5143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 5153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 5163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 5178462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 518345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 5198462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 52004f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 52104f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 5228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 5238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 524fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 525fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 526fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 527fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 528fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 529fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 530fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 531fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 532fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 533fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 534d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 535d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 536d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 537d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 538d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 539a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 540a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 543a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson void addShifterOperands(MCInst &Inst, unsigned N) const { 5450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 5460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Inst.addOperand(MCOperand::CreateImm( 5470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::getSORegOpc(Shift.ShiftTy, 0))); 5480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 5490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 55087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 5517729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 5525fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 5535fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 5547729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 5557729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 55687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 55787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 5580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 5590f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 5600f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 5610f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 5620f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 5630f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 5640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 5650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 5663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 5676b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 5686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 5696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 5706b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 5716b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 5726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 5736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 5746b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 5756b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 5766b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 5773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 5783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 5793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 58016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 581706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 582706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 583706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 584706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 585706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 586505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes void addMemMode7Operands(MCInst &Inst, unsigned N) const { 587505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert(N == 1 && isMemMode7() && "Invalid number of operands!"); 588505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 589505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 590505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 5911866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay (void)CE; 592505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert((CE || CE->getValue() == 0) && 593505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes "No offset operand support in mode 7"); 594505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 595505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 596ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes void addMemMode2Operands(MCInst &Inst, unsigned N) const { 597ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(isMemMode2() && "Invalid mode or number of operands!"); 598ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 599ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 600ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 601ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) { 602ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 603ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 604ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 605ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; 606ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t ShiftAmount = 0; 607ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 608ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetRegShifted()) { 609ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc = getMemShiftType(); 610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = 611ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes dyn_cast<MCConstantExpr>(getMemShiftAmount()); 612ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftAmount = CE->getValue(); 613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 614ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 615ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, 616ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc, IdxMode))); 617ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return; 618ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 619ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 620ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 621ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 622ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 623ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 624ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // the difference? 625ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 626ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(CE && "Non-constant mode 2 offset operand!"); 627ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Offset = CE->getValue(); 628ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 629ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Offset >= 0) 630ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, 631ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, ARM_AM::no_shift, IdxMode))); 632ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes else 633ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, 634ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes -Offset, ARM_AM::no_shift, IdxMode))); 635ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 636ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 637ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes void addMemMode3Operands(MCInst &Inst, unsigned N) const { 638ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(isMemMode3() && "Invalid mode or number of operands!"); 639ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 640ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 641ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 642ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 643ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 644ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 645ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 646ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0, 647ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes IdxMode))); 648ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return; 649ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 650ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 651ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 652ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 653ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 654ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 655ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // the difference? 656ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 657ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(CE && "Non-constant mode 3 offset operand!"); 658ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Offset = CE->getValue(); 659ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 660ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Offset >= 0) 661ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add, 662ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Offset, IdxMode))); 663ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes else 664ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub, 665ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes -Offset, IdxMode))); 666ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 667ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 66814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner void addMemMode5Operands(MCInst &Inst, unsigned N) const { 66914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 67016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 6714b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 6724b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar assert(!getMemOffsetIsReg() && "Invalid mode 5 operand"); 67392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 67480eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // FIXME: #-0 is encoded differently than #0. Does the parser preserve 67580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // the difference? 6764b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 677d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert(CE && "Non-constant mode 5 offset operand!"); 678d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 679d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // The MCInst offset operand doesn't include the low two bits (like 680d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // the instruction encoding). 681d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar int64_t Offset = CE->getValue() / 4; 682d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar if (Offset >= 0) 683d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, 684d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Offset))); 685d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar else 686d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, 687d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar -Offset))); 68814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 6893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 690f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const { 691f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!"); 6924b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 6934b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 694f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 695ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 696f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const { 697f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!"); 6984b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 6994b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 700f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(CE && "Non-constant mode offset operand!"); 701f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 702ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 703ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 704584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 705584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 706584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 707584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 708584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 709a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 710a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 711a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 712a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 713a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 714fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar virtual void dump(raw_ostream &OS) const; 715b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 7163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 7173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 718345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 719345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 720345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 7213a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 722345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 723345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 724fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 725fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 726fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 727fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 728fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 729fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 730fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 731fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 732fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 733fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 734fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 736fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 737fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 738fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 739fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 740d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 741d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 742d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 743d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 744d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 745d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 746d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 747d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 7483a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 7493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 750762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 751762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 752762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 753762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 7543a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 755a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 756a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 75750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 7583a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 759762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 760762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 761762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 7623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 763a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 764a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy, 7660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 7670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARMOperand *Op = new ARMOperand(Shifter); 7680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->Shift.ShiftTy = ShTy; 7690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 7700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 7710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 7720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 7730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 7747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 7755fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 776cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 7770f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 7780f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling if (ARM::DPRRegClass.contains(Regs.front().first)) 7800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 7810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling else if (ARM::SPRRegClass.contains(Regs.front().first)) 7820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 7830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 7855fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 7867729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 78724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 788cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 789cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 790cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 7918d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 7928d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 7938d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 7943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 7953a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 796762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 797762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 798762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 7993a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 800cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 801cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 802ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, 803ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool OffsetIsReg, const MCExpr *Offset, 804ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int OffsetRegNum, bool OffsetRegShifted, 8050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType, 8063a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *ShiftAmount, bool Preindexed, 8073a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool Postindexed, bool Negative, bool Writeback, 8083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 809023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((OffsetRegNum == -1 || OffsetIsReg) && 810023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegNum must imply OffsetIsReg!"); 811023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!OffsetRegShifted || OffsetIsReg) && 812023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegShifted must imply OffsetIsReg!"); 813d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert((Offset || OffsetIsReg) && 814d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar "Offset must exists unless register offset is used!"); 815023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) && 816023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have shift amount without shifted register offset!"); 817023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!Offset || !OffsetIsReg) && 818023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have expression offset and register offset!"); 819023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar 8203a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Op->Mem.AddrMode = AddrMode; 822762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 823762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 8242637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar if (OffsetIsReg) 8252637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.RegNum = OffsetRegNum; 8262637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar else 8272637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.Value = Offset; 828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 829762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 830762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 831762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 832762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 833762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 834762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 83516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 836762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 837762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 8383a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 839a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 840706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 841706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 842706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 843706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 844706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 845706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 846706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 847706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 848a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 849a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 850a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 851a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 852a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 853a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 854a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 855a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 856584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 857584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 858584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 859584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 860584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 861584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 862584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 863584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 864a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 865a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 866a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 867a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 868fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const { 869fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 870fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 8716a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 872fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 873d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 874d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 875d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 876fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 877fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 878fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 879fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 880fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 881fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 882584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 883584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 884584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 885fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 886fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 887fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 888706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 889706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 890706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 891fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 8926ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 893ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << "am:" << ARMII::AddrModeToString(getMemAddrMode()) 894ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << " base:" << getMemBaseRegNum(); 8956ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) { 8966ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:<register " << getMemOffsetRegNum(); 8976ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetRegShifted()) { 8986ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-type:" << getMemShiftType(); 8996ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-amount:" << *getMemShiftAmount(); 9006ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 9016ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } else { 9026ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:" << *getMemOffset(); 9036ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 9046ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) 9056ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (offset-is-reg)"; 9066ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPreindexed()) 9076ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (pre-indexed)"; 9086ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPostindexed()) 9096ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (post-indexed)"; 9106ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemNegative()) 9116ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (negative)"; 9126ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemWriteback()) 9136ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (writeback)"; 9146ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 915fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 916a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 917a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 918a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 919a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 920a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 921a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 922a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 923a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 924a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 925fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 92650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 927fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 9280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson case Shifter: 9290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson OS << "<shifter " << getShiftOpcStr(Shift.ShiftTy) << ">"; 9300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 9310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 9320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 9330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 9348d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 9358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 9365fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 9375fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 9387729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 9397729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 9407729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 9418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 9428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 9438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 9448d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 9458d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 946fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 947fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 948fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 949fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 950fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 9513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9523483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 9533483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 9543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 9563483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9573483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 9583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 95969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 96069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 961bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky RegNo = TryParseRegister(); 962bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 963bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 964bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 965bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 9669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 967e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 968e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 9693a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 970e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() { 97118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 972a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 973d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 974a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 975a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 9760c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 9770c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 9780c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 9790c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 9800c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 9810c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 9820c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 9830c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 9840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 9850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 9860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 9870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 98869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 989b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 990e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 991e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 992d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 9930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// Try to parse a register name. The token must be an Identifier when called, 9940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// and if it is a register name the token is eaten and the register number is 9950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// returned. Otherwise return -1. 9960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// 9970082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::TryParseShiftRegister( 9980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 9990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 10000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 10010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 10020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 10040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 10050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 10060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 10070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 10080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 10090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 10100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 10110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 10120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 10140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return true; 10150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Parser.Lex(); // Eat shift-type operand; 10170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson int RegNum = TryParseRegister(); 10180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (RegNum == -1) 10190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Error(Parser.getTok().getLoc(), "register expected"); 10200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Operands.push_back(ARMOperand::CreateReg(RegNum,S, Parser.getTok().getLoc())); 10220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Operands.push_back(ARMOperand::CreateShifter(ShiftTy, 10230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 10240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 10260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 10270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 102950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 103050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 103150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1032e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1033e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1034e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 103550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 103650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1037e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 1038e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int RegNo = TryParseRegister(); 1039e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 104050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1041d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 104250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1043a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1044e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1045e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 104650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 104750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1048e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 104999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 105099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 105150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1052a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1053a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1054fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1055fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1056fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1057fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1058e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1059e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1060e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1061e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1062e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1063fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1064e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1065e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1066e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1067e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1068e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1069e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1070e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1071e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1072e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1073e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1074e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1075e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1076e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1077e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1078e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1079e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1080fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1081e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1082e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1083e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1084e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1085e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1086e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1087e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1088e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1089e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1090e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1091e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1092e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1093e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1094e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1095e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1096e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1097f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The 1098fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1099fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1100f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1101f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1102e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1103e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1104e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1105e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1106fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1107e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1109e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1110e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1111fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1112f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1113fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1114fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1115f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The 1116fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1117fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1118f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1119f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1120fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1121fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1122fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1123fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1124fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1125fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1126f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1127fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1128fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1129fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1130f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1131e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1132e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1133c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1134c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 113550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 113650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 113718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1138a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1139e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 114016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 11417729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 11427729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 11435fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1144d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 11457729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1146e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 11477729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1148d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 114918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1150d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1151c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1152c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 115350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1154c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1155e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 11561d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling int RegNum = TryParseRegister(); 1157c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1158c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 115950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1160c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1161d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1162e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1163e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1164e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1165e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1166e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1167e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1168e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1169e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1170e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1171e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1172e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 11737729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 11747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1175e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1176e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 117718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1178c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1179c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 118050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1181c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1182d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1183e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1184e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 118503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1186e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 11875fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1188e717610f53e0465cde198536561a3c00ce29d59fBill Wendling RI = Registers.begin(), RE = Registers.end(); 1189e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 11907caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned HighRegNum = getARMRegisterNumbering(RI->first); 11918e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 11928e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling 11937caebff83d90a59aa74876ff887e822387f479e0Bill Wendling DenseMap<unsigned, bool> RegMap; 11947caebff83d90a59aa74876ff887e822387f479e0Bill Wendling RegMap[HighRegNum] = true; 11957caebff83d90a59aa74876ff887e822387f479e0Bill Wendling 1196e717610f53e0465cde198536561a3c00ce29d59fBill Wendling for (++RI; RI != RE; ++RI) { 11977729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling const std::pair<unsigned, SMLoc> &RegInfo = *RI; 11987caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1199e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 12008e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1201e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 120250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1203e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1204e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 12058e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1206e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1207e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1208e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 12098e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling RegMap[Reg] = true; 12108e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1211e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1212e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 121350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 121450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1215d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1216d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1217f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1218f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1219f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1220706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1221706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1222706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1223706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1224706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1225706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1226706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1227706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1228706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1229706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1230706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1231706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1232706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1233706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1234706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1235706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1236706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1237f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1238706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1239706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1240706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1241f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1242706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1243706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 12448bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1245a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1246a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1247a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1248a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1249a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1250a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1251a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1252a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1253a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1254a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1255a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1256a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1257a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1258a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1259a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1260a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1261a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1262a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1263a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1264a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1265a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1266a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1267a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1268a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1269a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1270a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1271584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1272584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1273584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1274584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1276584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1277584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1278584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1279584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1280584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1281584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1282584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1283584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1284584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef SpecReg = Mask.slice(Start, Next); 1285584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1290584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1291584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1292584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1293584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1294584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvq", 0x8) // same as CPSR_c 1296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1298584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1299584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 13004b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 13054b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 130756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 130856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1309584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1310584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1311584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1312584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1321584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1322584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1329584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1330584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1331584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1332584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1333584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1334584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1337a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1338a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1339ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand. 1340ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1341ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1342e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1343ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1344ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode2)) 1345ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_NoMatch; 1346ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1347ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_Success; 1348ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1349ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1350ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand. 1351ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1352ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1353ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1354ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1355ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode3)) 1356ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_NoMatch; 1357ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1358ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_Success; 1359ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1360ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1361ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1362ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1363ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1364ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1365ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1366ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1367ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1368ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1369ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1370ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1371ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1372ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1373ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1374ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1375ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1376ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1377ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1378ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1379ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1380ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1381ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1382ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1383ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1384ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1385ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1386ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1387ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1388ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1389ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1390ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1391ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1392ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1393ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1394ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1395ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1396ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1397ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1398ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1399ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1400ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1401ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1402ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1403ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1404ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1405ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1406ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1407ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1408ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1409ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1410ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1411ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1412ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1413ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1414ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1415ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1416ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1417ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1418ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1419ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1420ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1421e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 14229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 142350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// 14249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 14259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 142650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 1427ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1428ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { 1429762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 143018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 1431a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 1432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1433b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 1434a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 143518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 1436550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (BaseRegTok.isNot(AsmToken::Identifier)) { 1437550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 143850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1439550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1440e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int BaseRegNum = TryParseRegister(); 1441e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (BaseRegNum == -1) { 1442550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 144350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1444550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 14460571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 14470571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 14480571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 14490571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar return true; 14500571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 1451a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 1452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 1453a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 1454a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 1455a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 145605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar ARMOperand *WBOp = 0; 145705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar int OffsetRegNum = -1; 145805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar bool OffsetRegShifted = false; 14590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl; 146005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *ShiftAmount = 0; 146105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *Offset = 0; 1462a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 14639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 14649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 1465a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 1466a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 1467b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 146805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1469550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 1470550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 147150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 147218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 1473550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 1474550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 147550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1476550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 1478b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 148018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 1481a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 1482ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // None of addrmode3 instruction uses "!" 1483ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3) 1484ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1485ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 148650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling WBOp = ARMOperand::CreateToken(ExclaimTok.getString(), 148750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc()); 1488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 1489b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 1490ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } else { // In addressing mode 2, pre-indexed mode always end with "!" 1491ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (AddrMode == ARMII::AddrMode2) 1492ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Preindexed = false; 1493a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 14940571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar } else { 14950571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The "[Rn" we have so far was not followed by a comma. 14960571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 149780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // If there's anything other than the right brace, this is a post indexing 149880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // addressing form. 1499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 1500b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1501a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 150218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 150303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1504e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 150580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Postindexed = true; 150680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Writeback = true; 150750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1508550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 1509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 151050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1511550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 151250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1513b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 151450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1515550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 151616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 1517550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 151850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1519a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 152005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar } 1521e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 152205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar // Force Offset to exist if used. 152305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!OffsetIsReg) { 152405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!Offset) 152505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Offset = MCConstantExpr::Create(0, getContext()); 1526ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } else { 1527ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) { 1528ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Error(E, "shift amount not supported"); 1529ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1530ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1531a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 153205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1533ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, 1534ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, OffsetRegNum, OffsetRegShifted, 1535ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftType, ShiftAmount, Preindexed, 1536ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Postindexed, Negative, Writeback, S, E)); 153705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (WBOp) 153805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Operands.push_back(WBOp); 153905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 154005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar return false; 1541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 15439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 15449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 15459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 15469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 15479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 15489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 15499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 15509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 1551762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 15520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 15539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 15549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 15559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 1556762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 1557762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 15589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 15599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 15609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 15619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 156218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 1563762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 15649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 1565b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 15669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 15679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 1568b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 15699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 15709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 157118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 15729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 1573e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc CurLoc = OffsetRegTok.getLoc(); 1574e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner OffsetRegNum = TryParseRegister(); 1575e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (OffsetRegNum != -1) { 1576550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 1577e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner E = CurLoc; 1578762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 15799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 1580d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 158112f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling // If we parsed a register as the offset then there can be a shift after that. 15829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 15839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 158418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 15859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 1586b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 15879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 158818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1589762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 15903472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 15919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 15929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 15939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 15949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 15959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 159618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 15979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 15989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 159916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1600b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 16019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 16029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 16039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 1604762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 16059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 16069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 16079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 16089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 1609a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 1610a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 1611a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 1612a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 16130082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St, 16140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E) { 161518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1616a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 1617a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 161838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 1619a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 16200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 1621a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 16220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 1623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 16240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 1625a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 16260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 1627a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 16280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 1629a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 1630a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 1631b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 1632a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 16339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 16340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (St == ARM_AM::rrx) 16359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 1636a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 16379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 163818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 16399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 16409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 1641b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 16429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 16439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 16449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 1645a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1646a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 1647a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1648a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 16499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 16509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 1651e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1652fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 1653762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 1654fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1655fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 1656fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 1657f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1658f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 1659fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 1660f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 1661f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 1662f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 1663f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 1664f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 1665fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1666a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 1667146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 1668146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 166950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 167067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Identifier: 167150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling if (!TryParseRegisterWithWriteBack(Operands)) 167250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 16730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (!TryParseShiftRegister(Operands)) 16740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 16750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1676e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1677e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 1678e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 167967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 168067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 1681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 1682515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 1683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 1684762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1685515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 168650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1687762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 168850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 168950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 169050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 1691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 169250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseMemory(Operands); 1693d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 169450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseRegisterList(Operands); 1695d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 1696079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 1697079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 1698762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1699b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 1700515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 1701515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 170250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1703762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 170450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 170550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 17069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 17079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 17087597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 17097597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 17107597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 17119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (ParsePrefix(RefKind)) 17129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 17139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17147597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 17157597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 17169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 17179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17187597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 17197597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 17209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 17217597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 17229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 17239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 1724a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1725a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1726a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 17277597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 17287597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 17297597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) { 17307597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 17319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 17338a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 17349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 17359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 17379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 17389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 17399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 17429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 17437597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 17449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 17457597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 17469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 17479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 17489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 17499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 17519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 17539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 17549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 17559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 17579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 17589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 17599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 17619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E, 17629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 17639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 17649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 17659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 17669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 17679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 17699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 17709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 17719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 17729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 17739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 17759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 17769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 17789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 17799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 17819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 17849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 17859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 17879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 17889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant); 17899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 17909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 17919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 17929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 17949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 17989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 17999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 18009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 1801352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 1802352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 1803352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 1804badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 1805a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopesstatic StringRef SplitMnemonic(StringRef Mnemonic, 1806a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned &PredicationCode, 1807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool &CarrySetting, 1808a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned &ProcessorIMod) { 1809352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 1810352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 1811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 1812352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 1813badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 1814352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 1815352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 18168ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar if (Mnemonic == "teq" || Mnemonic == "vceq" || 18178ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "movs" || 18188ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "svc" || 18198ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 18208ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vmls" || Mnemonic == "vnmls") || 18218ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vacge" || Mnemonic == "vcge" || 18228ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vclt" || 18238ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vacgt" || Mnemonic == "vcgt" || 18248ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vcle" || 18258ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" || 18268ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" || 1827d1f0bbee189ea7cd18d03c4f9f55d0a33b070814Jim Grosbach Mnemonic == "vqdmlal" || Mnemonic == "bics")) 1828352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 1829badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 1830352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // First, split out any predication code. 1831badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 1832345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("eq", ARMCC::EQ) 1833345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ne", ARMCC::NE) 1834345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hs", ARMCC::HS) 1835660a9ec4aa08b42a1379e5caa3935d301b1e27b7Jim Grosbach .Case("cs", ARMCC::HS) 1836345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lo", ARMCC::LO) 1837660a9ec4aa08b42a1379e5caa3935d301b1e27b7Jim Grosbach .Case("cc", ARMCC::LO) 1838345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("mi", ARMCC::MI) 1839345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("pl", ARMCC::PL) 1840345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vs", ARMCC::VS) 1841345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vc", ARMCC::VC) 1842345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hi", ARMCC::HI) 1843345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ls", ARMCC::LS) 1844345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ge", ARMCC::GE) 1845345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lt", ARMCC::LT) 1846345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("gt", ARMCC::GT) 1847345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("le", ARMCC::LE) 1848345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("al", ARMCC::AL) 1849345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Default(~0U); 1850badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar if (CC != ~0U) { 1851badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 1852352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = CC; 185352925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 1854345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1855352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 1856352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 1857352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 1858352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 1859352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" || 1860352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" || 1861352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" || 1862352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) { 1863352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 1864352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 1865352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 1866352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 1867a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 1868a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 1869a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 1870a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 1871a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 1872a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 1873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 1874a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 1875a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1876a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 1877a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 1878a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 1879a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1880a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1881a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1882352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 1883352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 18843771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 18853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 18863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 18873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 18883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 1889fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 1890fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 1891fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 1892eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 1893eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 1894eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 1895eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 1896be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 1897eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 1898eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 1899be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "eor" || Mnemonic == "smlal" || 1900ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 1901eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 1902eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 1903eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 1904eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 19053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 1906eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 1907eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 1908eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 1909eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 1910e47f3751d7770916f250a00a84316d412e959c00Bruno Cardoso Lopes Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" || 1911a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic == "clrex" || Mnemonic.startswith("cps")) { 19123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 19133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 19143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 19153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 1916fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 1917ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 1918fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 191963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 1920fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 1921badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 1922badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 1923badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 1924badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 1925badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1926badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 1927badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 1928badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar StringRef Head = Name.slice(Start, Next); 1929badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 1930352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 1931352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 1932a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 1933352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 1934a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Head = SplitMnemonic(Head, PredicationCode, CarrySetting, 1935a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod); 1936badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 19373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 19389717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 19393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 19403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 19413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 19423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 19433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 19443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 19453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 19463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 19473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode); 19483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 19493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 19503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 19513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 19523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 19533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 19543771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptCarrySet) { 19553771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 19563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 19573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 19583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // This mnemonic can't ever accept a carry set, but the user wrote one (or 19593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // misspelled another mnemonic). 19603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 19613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: Issue a nice error. 19623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 19633771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 19643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 19653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 19663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 19673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 19683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 19693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // This mnemonic can't ever accept a predication code, but the user wrote 19703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // one (or misspelled another mnemonic). 19713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 19723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: Issue a nice error. 1973badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 1974345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1975a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 1976a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 1977a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 1978a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 1979a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 1980a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 1981a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 1982a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 1983a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1984a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 1985a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1986a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1987345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 19885747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 19895747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 19905747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 1991a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 1992a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1993a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 19945747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 19955747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 19965747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 19975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 1998a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 1999fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (ParseOperand(Operands, Head)) { 2000cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2001cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2002cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2003a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2004a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 2005b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 2006a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2007a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 2008fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (ParseOperand(Operands, Head)) { 2009cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2010cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2011cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2012a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2013a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 201416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2015cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2016cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 201734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 2018cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2019146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 202034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 20219898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 2022ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2023ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2024fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 2025fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 2026fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2027fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 2028fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 2029fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 2030193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResultTy MatchResult, MatchResult2; 2031193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2032193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult != Match_Success) { 2033193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // If we get a Match_InvalidOperand it might be some arithmetic instruction 2034193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // that does not update the condition codes. So try adding a CCOut operand 2035193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // with a value of reg0. 2036193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult == Match_InvalidOperand) { 2037193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.insert(Operands.begin() + 1, 2038193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateCCOut(0, 2039193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ((ARMOperand*)Operands[0])->getStartLoc())); 2040193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2041193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult2 == Match_Success) 2042193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = Match_Success; 204344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby else { 204444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 2045193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.erase(Operands.begin() + 1); 204644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete CCOut; 204744a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby } 2048193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2049193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // If we get a Match_MnemonicFail it might be some arithmetic instruction 2050193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // that updates the condition codes if it ends in 's'. So see if the 2051193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut 2052193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // operand with a value of CPSR. 2053eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng else if (MatchResult == Match_MnemonicFail) { 2054193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // Get the instruction mnemonic, which is the first token. 2055193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken(); 2056193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (Mnemonic.substr(Mnemonic.size()-1) == "s") { 2057193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // removed the 's' from the mnemonic for matching. 2058193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1); 2059193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc(); 206044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 206144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin()); 206244a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete OldMnemonic; 206344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.insert(Operands.begin(), 2064193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateToken(MnemonicNoS, NameLoc)); 2065193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.insert(Operands.begin() + 1, 2066193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateCCOut(ARM::CPSR, NameLoc)); 2067193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2068193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult2 == Match_Success) 2069193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = Match_Success; 2070193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby else { 207144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 207244a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin()); 207344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete OldMnemonic; 207444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.insert(Operands.begin(), 2075193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateToken(Mnemonic, NameLoc)); 207644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 207744a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin() + 1); 207844a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete CCOut; 2079193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2080193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2081193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2082193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2083193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 2084e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 2085fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 2086fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 2087e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 2088e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2089e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 2090e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 2091e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 2092e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 2093e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 2094e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 209516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2096e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2097e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2098e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 209916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2100e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 2101e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 2102e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 2103e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 2104b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 2105b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 2106fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 210716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2108c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 2109146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 2110fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 2111fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 2112515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 2113ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2114ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 2115ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 2116ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 2117515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 2118515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 2119515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 2120515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 2121515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 2122515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 2123515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 2124515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 2125ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2126ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2127ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2128ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 2129ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 2130ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 2131ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 2132ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 2133ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 2134ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 2135ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2136ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2137aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2138ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2139ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 2140ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 214116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2142ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 2143ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 2144ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 2145b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2146ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2147ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2148ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2149b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2150ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 2151ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2152ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2153515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 2154515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 2155515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 2156515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2157515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2158b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2159515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2160515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 2161515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 2162515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2163515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2164515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2165515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2166515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 2167515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 2168515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 21696469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 21706469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 21716469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 21726469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 21736469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 21746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 21756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 21766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 21776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 21786469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 21796469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 21806469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 21816469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 21826469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2183515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2184515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2185b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2186515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 21876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 21886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 21896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 21906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 21916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2192642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 2193642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2194642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 2195515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2196515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2197515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2198515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 2199515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 2200515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 220118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2202515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2203515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 220438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 220558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 2206b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 220758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 22089e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 2209515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2210515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 2211515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2212515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 221318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2214b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2215515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2216515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 2217515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2218515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2219515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2220515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2221515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 2222515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 2223515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 222418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2225515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 2226515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 222718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 222858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 2229b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 223058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 2231b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2232515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2233515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 2234515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2235515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 223618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2237b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2238515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 223932869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 224032869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (!isThumb()) SwitchMode(); 22412a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 224232869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 224332869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (isThumb()) SwitchMode(); 22442a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2245eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 22462a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 2247515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2248515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2249515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 225090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 225190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 22529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 2253ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 2254ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 2255ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 225690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 2257ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 22583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 22590692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 22600692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 22613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 2262