ARMAsmParser.cpp revision 27debd60a152d39e421c57bce511f16d8439a670
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// The LLVM Compiler Infrastructure 4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source 6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details. 7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===// 9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h" 2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h" 23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 2589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach#include "llvm/Support/MathExtras.h" 26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 28fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h" 3075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h" 32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 33345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 34c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 4116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbachenum VectorLaneTy { NoLanes, AllLanes, IndexedLane }; 4398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 4494b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 45ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 48f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach struct { 49f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes Cond; // Condition for IT block. 50f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Mask:4; // Condition mask for instructions. 51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Starting at first 1 (from lsb). 52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '1' condition as indicated in IT. 53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '0' inverse of condition (else). 54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Count of instructions in IT block is 55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // 4 - trailingzeroes(mask) 56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool FirstCond; // Explicit flag for when we're parsing the 58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // First instruction in the IT block. It's 59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // implied in the mask, so needs special 60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // handling. 61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned CurPosition; // Current position in parsing of IT 63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // block. In range [0,3]. Initialized 64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // according to count of instructions in block. 65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // ~0U if no active IT block. 66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } ITState; 67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool inITBlock() { return ITState.CurPosition != ~0U;} 68a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach void forwardITPosition() { 69a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (!inITBlock()) return; 70a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Move to the next instruction in the IT block, if there is one. If not, 71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // mark the block as done. 72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach unsigned TZ = CountTrailingZeros_32(ITState.Mask); 73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (++ITState.CurPosition == 5 - TZ) 74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach ITState.CurPosition = ~0U; // Done with the IT block after this. 75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 76f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 77f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 78ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 79ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 860d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 959a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach bool parseDirectiveARM(SMLoc L); 961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 99515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 10189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool &CarrySetting, unsigned &ProcessorIMod, 10289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask); 1031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 104fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 10516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 106ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 107ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 108ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 109ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 110ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 111ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 112ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 11347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 11447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 11547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 116194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 117194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 118194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 119acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool hasV7Ops() const { 120acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::HasV7Ops; 121acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 12232869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 123ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 124ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 12532869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 126acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool isMClass() const { 127acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::FeatureMClass; 128acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 129ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1330692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 136a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 13889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 13943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 140f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 14143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 142f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 1439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OperandMatchResultTy parseCoprocOptionOperand( 1449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 14543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1468bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1488bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1508bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 155f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 156f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 157f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 158f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 159c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 160580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 162293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 164251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 1659d39036f62674606565217a10db28171b9594bc7Jim Grosbach OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 166862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&); 1677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index); 168ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 169ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 170a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 171a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 172a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 173a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 174eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 175eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 176ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 177ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 179ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1809ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 1819ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &); 182548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 183548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 185ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1867b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1877b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 19914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 200623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 201623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 20388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20412431329d617064d6e72dd040a58c1635cc261abJim Grosbach bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, 20512431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20612431329d617064d6e72dd040a58c1635cc261abJim Grosbach bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, 20712431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2084334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, 2094334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2104334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, 2114334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 212189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 213189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 214189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 21583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach bool processInstruction(MCInst &Inst, 216f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 217d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 218d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 219189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 220ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 22147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 222194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 223f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Match_RequiresNotITBlock, 224194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 225194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 22647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 22747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 228ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 22994b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 230ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 23132869205052430f45d598fba25ab878d8b29da2dEvan Cheng 232ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 233ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 234f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 235f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Not in an ITBlock to start with. 236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = ~0U; 237ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 238ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 2401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 2411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 242189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 2431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 2441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 24547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 24647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 2471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 2481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 250ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 25116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 25216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2533a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 2543a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 255a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 256a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 257146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CondCode, 26021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CCOut, 26121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ITCondMask, 26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocNum, 26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocReg, 2649b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach k_CoprocOption, 26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Immediate, 26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_FPImmediate, 26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MemBarrierOpt, 26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Memory, 26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_PostIndexRegister, 27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MSRMask, 27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ProcIFlags, 272460a90540b045c102012da2492999557e6840526Jim Grosbach k_VectorIndex, 27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Register, 27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RegisterList, 27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_DPRRegisterList, 27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_SPRRegisterList, 277862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach k_VectorList, 27898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach k_VectorListAllLanes, 2797636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach k_VectorListIndexed, 28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedRegister, 28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedImmediate, 28221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShifterImmediate, 28321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RotateImmediate, 28421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_BitfieldDescriptor, 28521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Token 286a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 287a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 28924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 290a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 297fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 298fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 299fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 300fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 3019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach unsigned Val; 3029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } CoprocOption; 3039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 3049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach struct { 30589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 30689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 30789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 30889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 30989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 31089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 31189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 31289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 313a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 314a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 315a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 326a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 327a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 329862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // A vector register list is a sequential list of 1 to 4 registers. 330862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach struct { 331862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned RegNum; 332862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count; 3337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned LaneIndex; 334862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } VectorList; 335862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 3368155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 337460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned Val; 338460a90540b045c102012da2492999557e6840526Jim Grosbach } VectorIndex; 339460a90540b045c102012da2492999557e6840526Jim Grosbach 340460a90540b045c102012da2492999557e6840526Jim Grosbach struct { 341cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 342cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 34316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3449d39036f62674606565217a10db28171b9594bc7Jim Grosbach struct { 3459d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned Val; // encoded 8-bit representation 3469d39036f62674606565217a10db28171b9594bc7Jim Grosbach } FPImm; 3479d39036f62674606565217a10db28171b9594bc7Jim Grosbach 3486a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 349a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 350a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 3517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 3527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 3537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 3547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 3557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 35657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned ShiftImm; // shift for OffsetReg. 35757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment; // 0 = no alignment specified 35857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // n = alignment in bytes (8, 16, or 32) 3597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 360e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach } Memory; 3610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 3620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 3637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 364f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 365f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 366f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 3677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 3687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 370580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 371e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 372580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 373e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 374e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 375e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 376e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 377e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 378af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 37992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 38092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 38192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 38292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 383af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 3847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 3857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 387293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 388293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 389293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 390293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 391a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 39216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 393146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 394146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 395762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 396762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 397762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 398762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 399762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 40021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 4018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 4028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 40321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: 40489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 40589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 4078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 408762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 40921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 41021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 411762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 412762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 41321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 41521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: 41624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 4178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 418862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 41998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case k_VectorListAllLanes: 4207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case k_VectorListIndexed: 421862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach VectorList = o.VectorList; 422862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 42321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 42421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 425fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 426fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 4279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 4289b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach CoprocOption = o.CoprocOption; 4299b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 43021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 431762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 43321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 4349d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImm = o.FPImm; 4359d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 43621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 437706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 438706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 440e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory = o.Memory; 441762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 44221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 4437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 4447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 44521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 446584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 447584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 44821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: 449a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 4500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 45121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 4530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 455af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 45721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 458af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 45992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 46021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 4617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 4627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 46321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 464293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 465293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 466460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 467460a90540b045c102012da2492999557e6840526Jim Grosbach VectorIndex = o.VectorIndex; 468460a90540b045c102012da2492999557e6840526Jim Grosbach break; 469762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 470762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 47116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 472762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 47821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_CondCode && "Invalid access!"); 4798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 4808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 482fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 48321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 484fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 485fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 486fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 48821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Token && "Invalid access!"); 489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 4947729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4975fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind == k_SPRRegisterList) && "Invalid access!"); 50024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 5018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 5028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 503cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 50421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Immediate && "Invalid access!"); 505cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 506cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 507cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 5089d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned getFPImm() const { 50921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_FPImmediate && "Invalid access!"); 5109d39036f62674606565217a10db28171b9594bc7Jim Grosbach return FPImm.Val; 5119d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 5129d39036f62674606565217a10db28171b9594bc7Jim Grosbach 513460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned getVectorIndex() const { 514460a90540b045c102012da2492999557e6840526Jim Grosbach assert(Kind == k_VectorIndex && "Invalid access!"); 515460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val; 516460a90540b045c102012da2492999557e6840526Jim Grosbach } 517460a90540b045c102012da2492999557e6840526Jim Grosbach 518706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 51921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MemBarrierOpt && "Invalid access!"); 520706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 521706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 522706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_ProcIFlags && "Invalid access!"); 525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 527a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 528584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MSRMask && "Invalid access!"); 530584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 531584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 532584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 53321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocNum() const { return Kind == k_CoprocNum; } 53421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocReg() const { return Kind == k_CoprocReg; } 5359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach bool isCoprocOption() const { return Kind == k_CoprocOption; } 53621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCondCode() const { return Kind == k_CondCode; } 53721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCCOut() const { return Kind == k_CCOut; } 53821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITMask() const { return Kind == k_ITCondMask; } 53921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITCondCode() const { return Kind == k_CondCode; } 54021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isImm() const { return Kind == k_Immediate; } 54121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isFPImm() const { return Kind == k_FPImmediate; } 542a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isImm8s4() const { 54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 544a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 545a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 546a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!CE) return false; 547a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Value = CE->getValue(); 548a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 549a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 55072f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 55121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 55272f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 55372f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 55472f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 55572f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 55672f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 55772f39f8436848885176943b0ba985a7171145423Jim Grosbach } 55872f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 55921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 56072f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 56172f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 56272f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 56372f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 56472f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 56572f39f8436848885176943b0ba985a7171145423Jim Grosbach } 5666b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 56721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5706b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5716b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 5736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 574587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach bool isImm0_1() const { 575587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (Kind != k_Immediate) 576587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return false; 577587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 578587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (!CE) return false; 579587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach int64_t Value = CE->getValue(); 580587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return Value >= 0 && Value < 2; 581587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach } 582587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach bool isImm0_3() const { 583587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (Kind != k_Immediate) 584587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return false; 585587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 586587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (!CE) return false; 587587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach int64_t Value = CE->getValue(); 588587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return Value >= 0 && Value < 4; 589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach } 59083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 59121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 59283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 59383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 59483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 59583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 59683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 59783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 59883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 59921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 60083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 60183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 60283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 60383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 60483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 6067c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 60721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6087c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 6097c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6107c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 6117c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 6127c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 6137c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 614730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach bool isImm0_63() const { 615730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach if (Kind != k_Immediate) 616730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach return false; 617730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 618730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach if (!CE) return false; 619730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach int64_t Value = CE->getValue(); 620730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach return Value >= 0 && Value < 64; 621730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach } 6223b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm8() const { 6233b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6243b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6253b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6263b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6273b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6283b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value == 8; 6293b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6303b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm16() const { 6313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6323b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6343b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6353b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6363b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value == 16; 6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm32() const { 6393b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6403b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6413b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6423b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6433b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6443b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value == 32; 6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6466b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm8() const { 6476b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6486b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6496b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6506b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6516b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6526b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 8; 6536b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm16() const { 6556b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6566b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6576b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6586b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6596b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6606b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 16; 6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm32() const { 6636b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6646b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6656b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6666b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6676b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6686b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 32; 6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6706b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm64() const { 6716b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6726b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6736b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6746b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6756b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6766b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 64; 6776b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6783b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_7() const { 6793b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6803b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6813b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6823b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6833b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6843b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value > 0 && Value < 8; 6853b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_15() const { 6873b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6883b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6893b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6903b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6913b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6923b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value > 0 && Value < 16; 6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_31() const { 6953b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6963b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6973b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6983b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6993b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 7003b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value > 0 && Value < 32; 7013b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 702f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 70321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 704f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 705f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 706f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 707f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 708f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 709f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 71121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 7124a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 7134a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 7154a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 7164a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 7174a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 718ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach bool isImm0_32() const { 719ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (Kind != k_Immediate) 720ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach return false; 721ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 722ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (!CE) return false; 723ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach int64_t Value = CE->getValue(); 724ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach return Value >= 0 && Value < 33; 725ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach } 726fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 72721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 728fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 729fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 730fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 731fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 732fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 733fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 734ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 73521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 736ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 737ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 738ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 739ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 740ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 741ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 742ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 743ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 744ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 74521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 746ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 747ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 748ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 749ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 750ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 751ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 75270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 75321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 75470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 75570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 75670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 75770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 75870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 75970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 76121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 766f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 767f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 768f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 76921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 770f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 771f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 772f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 773f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 774f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 775f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 7766bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 77721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 7786bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 7796bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7806bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 7816bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 7826bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 7836bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 784e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach bool isARMSOImmNot() const { 785e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach if (Kind != k_Immediate) 786e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach return false; 787e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 788e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach if (!CE) return false; 789e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach int64_t Value = CE->getValue(); 790e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach return ARM_AM::getSOImmVal(~Value) != -1; 791e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach } 7923bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach bool isARMSOImmNeg() const { 7933bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (Kind != k_Immediate) 7943bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return false; 7953bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7963bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (!CE) return false; 7973bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach int64_t Value = CE->getValue(); 7983bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return ARM_AM::getSOImmVal(-Value) != -1; 7993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 8006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 80121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 8026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 8036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 8056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 8066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 8076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 80889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach bool isT2SOImmNot() const { 80989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach if (Kind != k_Immediate) 81089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach return false; 81189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 81289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach if (!CE) return false; 81389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach int64_t Value = CE->getValue(); 81489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach return ARM_AM::getT2SOImmVal(~Value) != -1; 81589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach } 8163bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach bool isT2SOImmNeg() const { 8173bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (Kind != k_Immediate) 8183bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return false; 8193bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8203bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (!CE) return false; 8213bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach int64_t Value = CE->getValue(); 8223bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return ARM_AM::getT2SOImmVal(-Value) != -1; 8233bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 824c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 82521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 826c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 827c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 828c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 829c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 830c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 831c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 83221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isReg() const { return Kind == k_Register; } 83321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegList() const { return Kind == k_RegisterList; } 83421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 83521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 83621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isToken() const { return Kind == k_Token; } 83721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 83821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemory() const { return Kind == k_Memory; } 83921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isShifterImm() const { return Kind == k_ShifterImmediate; } 84021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 84121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 84221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRotImm() const { return Kind == k_RotateImmediate; } 84321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 84421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 845f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 846430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift; 847f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 84857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isMemNoOffset(bool alignOK = false) const { 849f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 850ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 8517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 85257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 && 85357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach (alignOK || Memory.Alignment == 0); 85457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 85557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isAlignedMemory() const { 85657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return isMemNoOffset(true); 857ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 85957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 861e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 8627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 863e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 864e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 8667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 867039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 86821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 869039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 870039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 871039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 872039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 873039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 874039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 875039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 8762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 87757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 8782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 879e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::no_shift) return false; 8802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 881e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 8822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 883e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 884e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 8862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 88821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate && Kind != k_PostIndexRegister) 8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 89021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) 8912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 8952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 896251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 897251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 8982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 8997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 900681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // If we have an immediate that's not a constant, treat it as a label 901681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // reference needing a fixup. If it is a constant, it's something else 902681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // and we reject it. 903681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 904681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach return true; 90557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 9067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 907e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return false; 9087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 909e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 910e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 9110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 912681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Val == INT32_MIN; 9137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 9147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBB() const { 915e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 91657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 9177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 9187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 9197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 9207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBH() const { 921e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 92257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 92357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0 ) 9247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 9257f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 9267f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 9277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 92857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0) 929ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 930ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 931ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 932ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach bool isT2MemRegOffset() const { 93357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 93457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0) 935ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 936ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach // Only lsl #{0, 1, 2, 3} allowed. 937e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType == ARM_AM::no_shift) 938ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 939e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 940ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 941ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 942ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 9447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 9457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 946e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 94757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 94887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 949e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach return isARMLowRegister(Memory.BaseRegNum) && 950e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 95160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 95260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 953e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 95457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 95560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 95660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 957e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 958e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 959ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 960ecd858968384be029574d845eb098d357049e02eJim Grosbach } 96138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 962e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 96357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 96438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 96538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 966e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 967e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 96838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 96938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 97048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 971e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 97257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 97348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 97448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 975e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 976e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 97748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 97848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 979ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 98057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 98157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 982ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 983ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 984e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 985e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 986ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 987505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 988a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isMemImm8s4Offset() const { 98957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 990a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 991a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate offset a multiple of 4 in range [-1020, 1020]. 992e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 993e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 995a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 996b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach bool isMemImm0_1020s4Offset() const { 99757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 998b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return false; 999b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // Immediate offset a multiple of 4 in range [0, 1020]. 1000e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1001e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 1003b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 10047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 100557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1006f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 10077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 1008e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1009e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 10104d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson return (Val == INT32_MIN) || (Val > -256 && Val < 256); 1011f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1012f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach bool isMemPosImm8Offset() const { 101357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1014f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return false; 1015f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach // Immediate offset in range [0, 255]. 1016e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1017e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1018f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return Val >= 0 && Val < 256; 1019f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1020a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemNegImm8Offset() const { 102157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1022a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 1023a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [-255, -1]. 1024df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach if (!Memory.OffsetImm) return false; 1025e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1026df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach return (Val == INT32_MIN) || (Val > -256 && Val < 0); 1027a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1028a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemUImm12Offset() const { 102957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1030a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 1031a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [0, 4095]. 1032e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1033e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1034a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return (Val >= 0 && Val < 4096); 1035a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 10367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 103709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 103809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 103909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 104021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 104109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 104209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 104357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1044ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 10457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 1046e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1047e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 10480da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 10497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 10507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 105121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 10527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 10537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1054ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 10557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 105663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 1057ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 10582bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isPostIdxImm8s4() const { 10592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Kind != k_Immediate) 10602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return false; 10612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (!CE) return false; 10632bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int64_t Val = CE->getValue(); 10642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 10652bd0118472de352745a2e038245fab4974f7c87eJim Grosbach (Val == INT32_MIN); 10662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 10677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 106821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMSRMask() const { return Kind == k_MSRMask; } 106921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isProcIFlags() const { return Kind == k_ProcIFlags; } 10703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 10710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // NEON operands. 1072862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach bool isVecListOneD() const { 1073862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Kind != k_VectorList) return false; 1074862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return VectorList.Count == 1; 1075862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1076862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1077280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach bool isVecListTwoD() const { 1078280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach if (Kind != k_VectorList) return false; 1079280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach return VectorList.Count == 2; 1080280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach } 1081280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach 1082cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach bool isVecListThreeD() const { 1083cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach if (Kind != k_VectorList) return false; 1084cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach return VectorList.Count == 3; 1085cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach } 1086cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach 1087b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach bool isVecListFourD() const { 1088b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach if (Kind != k_VectorList) return false; 1089b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach return VectorList.Count == 4; 1090b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach } 1091b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach 10924661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach bool isVecListTwoQ() const { 10934661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach if (Kind != k_VectorList) return false; 10944661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach //FIXME: We haven't taught the parser to handle by-two register lists 10954661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach // yet, so don't pretend to know one. 10964661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach return VectorList.Count == 2 && false; 10974661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach } 10984661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach 109998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach bool isVecListOneDAllLanes() const { 110098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Kind != k_VectorListAllLanes) return false; 110198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return VectorList.Count == 1; 110298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 110398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 110413af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach bool isVecListTwoDAllLanes() const { 110513af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach if (Kind != k_VectorListAllLanes) return false; 110613af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach return VectorList.Count == 2; 110713af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach } 110813af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach 11097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach bool isVecListOneDByteIndexed() const { 11107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (Kind != k_VectorListIndexed) return false; 11117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return VectorList.Count == 1 && VectorList.LaneIndex <= 7; 11127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 11137636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 1114460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex8() const { 1115460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1116460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 8; 1117460a90540b045c102012da2492999557e6840526Jim Grosbach } 1118460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex16() const { 1119460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1120460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 4; 1121460a90540b045c102012da2492999557e6840526Jim Grosbach } 1122460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex32() const { 1123460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1124460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 2; 1125460a90540b045c102012da2492999557e6840526Jim Grosbach } 1126460a90540b045c102012da2492999557e6840526Jim Grosbach 11270e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach bool isNEONi8splat() const { 11280e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (Kind != k_Immediate) 11290e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return false; 11300e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11310e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Must be a constant. 11320e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!CE) return false; 11330e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach int64_t Value = CE->getValue(); 11340e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // i8 value splatted across 8 bytes. The immediate is just the 8 byte 11350e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // value. 11360e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return Value >= 0 && Value < 256; 11370e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 1138460a90540b045c102012da2492999557e6840526Jim Grosbach 1139ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach bool isNEONi16splat() const { 1140ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Kind != k_Immediate) 1141ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return false; 1142ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1143ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // Must be a constant. 1144ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (!CE) return false; 1145ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach int64_t Value = CE->getValue(); 1146ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // i16 value in the range [0,255] or [0x0100, 0xff00] 1147ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00); 1148ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1149ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 11506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32splat() const { 11516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 11526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 11536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 11556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 11566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 11576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X. 11586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 11596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 11606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 11616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000); 11626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 11636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 11646248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32vmov() const { 11656248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 11666248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 11676248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11686248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 11696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 11706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 11716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 11726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 11736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 11746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 11756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 11766248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000) || 11776248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 11786248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 11796248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 11806248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1181f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach bool isNEONi64splat() const { 1182f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (Kind != k_Immediate) 1183f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return false; 1184f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1185f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // Must be a constant. 1186f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (!CE) return false; 1187f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1188f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // i64 value with each byte being either 0 or 0xff. 1189f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i) 1190f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 1191f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return true; 1192f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1193f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 11943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 119514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 119614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 119714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 119814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 11993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 12003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 12013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 12023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 12033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1205345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 12068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 120704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 120804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 12098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 12108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1211fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 1212fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1213fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 1214fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1215fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 12169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 12179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 12189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(getCoproc())); 12199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 12209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 12219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 12229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 12239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val)); 12249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 12259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 122689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 122789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 122889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 122989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 123089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 123189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 123289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 123389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 123489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 123589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 1236d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 1237d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1238d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 1239d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1240d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 1241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 1242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 1243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 1244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1246af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 1247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1248430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach assert(isRegShiftedReg() && 1249430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach "addRegShiftedRegOperands() on non RegShiftedReg!"); 1250af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 1251af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 1252e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 1253af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 1254e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1255e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1256af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 1257152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 1258430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach assert(isRegShiftedImm() && 1259430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach "addRegShiftedImmOperands() on non RegShiftedImm!"); 1260af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 126192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 1262af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 126392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 126492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1265580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 12660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 1267580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 1268580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 12690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 12700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 127187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 12727729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 12735fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 12745fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 12757729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 12767729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 127787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 127887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 12790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 12800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 12810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 12820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 12830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 12840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 12850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 12860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 12877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 12887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 12897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 12907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 12917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 12927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1294293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1295293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 1296293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 1297293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 1298293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1299293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1300293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 1301293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 1302293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1303293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 13043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 13056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 13076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 13086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 13099d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 13109d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13119d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 13129d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 13139d39036f62674606565217a10db28171b9594bc7Jim Grosbach 1314a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1315a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1316a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 1317a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 1318a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1319a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1320a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1321a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 132272f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 132372f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 132472f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 132572f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 132672f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 132772f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 132872f39f8436848885176943b0ba985a7171145423Jim Grosbach } 132972f39f8436848885176943b0ba985a7171145423Jim Grosbach 133072f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 133172f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 133272f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 133372f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 133472f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 133572f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 133672f39f8436848885176943b0ba985a7171145423Jim Grosbach } 133772f39f8436848885176943b0ba985a7171145423Jim Grosbach 1338f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1339f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1340f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1341f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1342f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1343f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1344f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1345f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 13464a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 13474a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 13484a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 13494a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 13504a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 13514a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 13524a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 13534a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 135470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 135570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 135670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 135770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 135870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 135970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 136070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1361ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1362ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1366f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1367f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1371f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 137289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const { 137389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 137489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach // The operand is actually a t2_so_imm, but we have its bitwise 137589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach // negation in the assembly source, so twiddle it here. 137689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 137789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 137889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach } 137989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach 13803bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const { 13813bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 13823bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // The operand is actually a t2_so_imm, but we have its 13833bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // negation in the assembly source, so twiddle it here. 13843bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 13853bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 13863bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 13873bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach 1388e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const { 1389e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1390e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach // The operand is actually a so_imm, but we have its bitwise 1391e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach // negation in the assembly source, so twiddle it here. 1392e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1393e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 1394e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach } 1395e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach 13963bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const { 13973bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 13983bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // The operand is actually a so_imm, but we have its 13993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // negation in the assembly source, so twiddle it here. 14003bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 14023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 14033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach 1404706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1405706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1406706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1407706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1408706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 14097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 14107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1411e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1412505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1413505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 141457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 141557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 141657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 141757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 141857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 141957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 14207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 14217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1422e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1423e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 14247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 14257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 14267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 14277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 14287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 14297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 14307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 14317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 1432e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1433e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1434ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1435e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1436e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1438ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1439ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1440039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1441039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1442039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1443039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1444039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1445039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1446039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1447039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1448039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1449039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1450039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1451039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1452039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1453039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 14542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 14552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1456e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1457e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 14582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 14592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 14602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 14612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 14622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 14632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 14642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 14652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 1466e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 14672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 1468e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1469e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 14722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 14732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 14742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 147521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) { 14762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 14772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 14782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 14792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1480251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 14812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 14822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 14832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 14842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 14852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 14862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 14872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 14882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 14892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1490251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 14912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 14922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 14942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 14957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 14967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1497681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // If we have an immediate that's not a constant, treat it as a label 1498681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // reference needing a fixup. If it is a constant, it's something else 1499681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // and we reject it. 1500681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach if (isImm()) { 1501681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Inst.addOperand(MCOperand::CreateExpr(getImm())); 1502681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1503681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach return; 1504681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach } 1505681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach 15067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1507e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 15087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 15097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 15107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 15117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 15127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 1513e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 15147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 15157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 15167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1517a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1518a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1519e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1520e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1521a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1522a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1523a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1524b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1525b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1526b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1527e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1528e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1529b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1530b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1531b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 15327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 15337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1534e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1535e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 15367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1537ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1538ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1539f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1540f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1541f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1542f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1543a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1544f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1545a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1546a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1547a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1548a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1549a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 155021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 1551a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1552a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1553a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1554a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1555a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1556a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1557e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1558e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1559a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1560a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1561a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 15627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 15637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 156409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 156521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 156609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 156709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 156809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 156909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 157009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 157109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1572e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1573e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 15747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 15757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 157692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 15777f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 15787f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1579e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1580e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 15817f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 15827f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 15837f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 15847f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1585e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1586e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 15877f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 15887f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 15897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 15907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1591430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach unsigned Val = 1592430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1593430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach Memory.ShiftImm, Memory.ShiftType); 1594e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1595e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 15967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 15977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1598d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1599ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1600ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1601e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1602e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1603e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 1604ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1605ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 16067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 16077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1608e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1609e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 161014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 16113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 161260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 161360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1614e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1615e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 161660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 161748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 161848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 161938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 162038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1621e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 1622e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 162338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 162438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 162538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 162648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 162748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1628e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 1629e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 163048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 163160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 163260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1633ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1634ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1635e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1636e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1637ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1638ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1639ecd858968384be029574d845eb098d357049e02eJim Grosbach 16407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 16417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 16427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 16437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 16447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 16457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 164663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 16477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 16487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1649f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1650ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 16512bd0118472de352745a2e038245fab4974f7c87eJim Grosbach void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 16522bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 16532bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 16542bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(CE && "non-constant post-idx-imm8s4 operand!"); 16552bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int Imm = CE->getValue(); 16562bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isAdd = Imm >= 0; 16572bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Imm == INT32_MIN) Imm = 0; 16582bd0118472de352745a2e038245fab4974f7c87eJim Grosbach // Immediate is scaled by 4. 16592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 16602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 16612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 16622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach 16637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 16647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 16657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1666f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1667f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1668f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1669f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1670f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1671f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1672f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1673f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1674f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1675f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1676f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1677f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1678ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1679ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1680584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1681584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1682584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1683584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1684584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1685a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1686a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1687a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1688a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1689a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 16906029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach void addVecListOperands(MCInst &Inst, unsigned N) const { 1691862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1692862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1693862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1694862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 16957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach void addVecListIndexedOperands(MCInst &Inst, unsigned N) const { 16967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 16977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 16987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex)); 16997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 17007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 1701460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1702460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1703460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1704460a90540b045c102012da2492999557e6840526Jim Grosbach } 1705460a90540b045c102012da2492999557e6840526Jim Grosbach 1706460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1707460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1708460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1709460a90540b045c102012da2492999557e6840526Jim Grosbach } 1710460a90540b045c102012da2492999557e6840526Jim Grosbach 1711460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1712460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1713460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1714460a90540b045c102012da2492999557e6840526Jim Grosbach } 1715460a90540b045c102012da2492999557e6840526Jim Grosbach 17160e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 17170e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 17180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // The immediate encodes the type of constant as well as the value. 17190e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Mask in that this is an i8 splat. 17200e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 17210e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00)); 17220e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 17230e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 1724ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 1725ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1726ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // The immediate encodes the type of constant as well as the value. 1727ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1728ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach unsigned Value = CE->getValue(); 1729ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Value >= 256) 1730ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value = (Value >> 8) | 0xa00; 1731ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach else 1732ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value |= 0x800; 1733ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 1734ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1735ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 17366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 17376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 17386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 17396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 17406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 17416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xff00) 17426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | 0x200; 17436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xff0000) 17446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | 0x400; 17456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 17466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 17476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 17486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 17496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 17506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 17516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 17526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 17536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 17546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 17556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xffff) 17566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 17576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xffffff) 17586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 17596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 17606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 17616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 17626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 17636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1764f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 1765f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1766f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // The immediate encodes the type of constant as well as the value. 1767f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1768f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1769f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach unsigned Imm = 0; 1770f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 1771f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Imm |= (Value & 1) << i; 1772f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1773f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00)); 1774f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1775f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 1776b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1777b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 177889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 177921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ITCondMask); 178089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 178189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 178289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 178389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 178489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 178589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 17863a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 178721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CondCode); 1788345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1789345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1790345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 17913a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1792345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1793345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1794fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 179521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocNum); 1796fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1797fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1798fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1799fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1800fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1801fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1802fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 180321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocReg); 1804fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1805fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1806fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1807fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1808fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1809fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 18109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) { 18119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocOption); 18129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->Cop.Val = Val; 18139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->StartLoc = S; 18149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->EndLoc = E; 18159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return Op; 18169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 18179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 1818d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 181921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CCOut); 1820d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1821d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1822d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1823d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1824d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1825d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 18263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 182721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Token); 1828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1829762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1830762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1831762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 18323a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1833a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1834a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 183550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 183621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Register); 1837762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1838762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1839762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 18403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1841a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1842a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1843e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1844e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1845e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1846e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1847e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 184821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1849af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1850af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1851af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1852af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1853e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1854e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1855e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1856e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1857e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 185892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 185992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 186092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 186192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 186221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1863af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1864af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1865af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 186692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 186792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 186892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 186992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 187092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1871580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 18720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 187321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1874580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1875580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 18760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 18770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 18780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 18790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 18800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 18817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 188221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_RotateImmediate); 18837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 18847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 18857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 18867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 18877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 18887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1889293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1890293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 189121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 1892293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1893293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1894293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1895293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1896293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1897293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1898293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 18997729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 19005fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1901cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 190221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach KindTy Kind = k_RegisterList; 19030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1904d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 190521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_DPRRegisterList; 1906d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1907275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 190821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_SPRRegisterList; 19090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 19100f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 19115fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 19127729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 191324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1914cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1915cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1916cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 19178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 19188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 19198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 1920862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count, 1921862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc S, SMLoc E) { 1922862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorList); 1923862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.RegNum = RegNum; 1924862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.Count = Count; 1925862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->StartLoc = S; 1926862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->EndLoc = E; 1927862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return Op; 1928862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1929862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 193098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count, 193198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc S, SMLoc E) { 193298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorListAllLanes); 193398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->VectorList.RegNum = RegNum; 193498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->VectorList.Count = Count; 193598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->StartLoc = S; 193698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->EndLoc = E; 193798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Op; 193898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 193998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 19407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count, 19417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned Index, SMLoc S, SMLoc E) { 19427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorListIndexed); 19437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.RegNum = RegNum; 19447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.Count = Count; 19457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.LaneIndex = Index; 19467636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->StartLoc = S; 19477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->EndLoc = E; 19487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return Op; 19497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 19507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 1951460a90540b045c102012da2492999557e6840526Jim Grosbach static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 1952460a90540b045c102012da2492999557e6840526Jim Grosbach MCContext &Ctx) { 1953460a90540b045c102012da2492999557e6840526Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorIndex); 1954460a90540b045c102012da2492999557e6840526Jim Grosbach Op->VectorIndex.Val = Idx; 1955460a90540b045c102012da2492999557e6840526Jim Grosbach Op->StartLoc = S; 1956460a90540b045c102012da2492999557e6840526Jim Grosbach Op->EndLoc = E; 1957460a90540b045c102012da2492999557e6840526Jim Grosbach return Op; 1958460a90540b045c102012da2492999557e6840526Jim Grosbach } 1959460a90540b045c102012da2492999557e6840526Jim Grosbach 19603a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 196121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Immediate); 1962762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1963762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1964762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 19653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1966cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1967cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 19689d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 196921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_FPImmediate); 19709d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 19719d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 19729d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 19739d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 19749d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 19759d39036f62674606565217a10db28171b9594bc7Jim Grosbach 19767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 19777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 19787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 19797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 19800d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 198157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment, 19827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 19833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 198421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Memory); 1985e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.BaseRegNum = BaseRegNum; 1986e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetImm = OffsetImm; 1987e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetRegNum = OffsetRegNum; 1988e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftType = ShiftType; 1989e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftImm = ShiftImm; 199057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Op->Memory.Alignment = Alignment; 1991e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.isNegative = isNegative; 19927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 19937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 19947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 19957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 199616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1997f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1998f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1999f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 20007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 200121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 20027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 2003f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 2004f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 2005f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 2006762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 2007762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 20083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 2009a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2010706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2011706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 201221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 2013706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 2014706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 2015706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 2016706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 2017706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 2018a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2019a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 202021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ProcIFlags); 2021a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 2022a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 2023a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 2024a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 2025a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2026584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2027584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 202821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MSRMask); 2029584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 2030584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 2031584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 2032584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 2033584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2034a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 2035a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2036a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 2037a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2038b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 2039fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 204021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 20419d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 20429d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 20439d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 204421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 20456a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 2046fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 204721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 2048d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 2049d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 205021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: { 20511a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer static const char *MaskStr[] = { 20521a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)", 20531a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)" 20541a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer }; 205589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 205689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 205789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 205889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 205921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 2060fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 2061fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 206221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 2063fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 2064fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 20659b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 20669b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OS << "<coprocessor option: " << CoprocOption.Val << ">"; 20679b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 206821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 2069584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 2070584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 207121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 2072fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 2073fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 207421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 2075706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 2076706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 207721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 20786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 2079e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach << " base:" << Memory.BaseRegNum; 20806ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 2081fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 208221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 2083f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 2084f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 2085f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 2086f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 2087f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 2088f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 20897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 209021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: { 2091a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 2092a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 2093a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 2094a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 2095a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 2096a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 2097a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 2098a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 209921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 210050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 2101fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 210221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 2103580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 2104580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 2105e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 210621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 210792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 2108efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << RegShiftedReg.SrcReg << " " 2109efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) 2110efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << " " << RegShiftedReg.ShiftReg << ">"; 21110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 211221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 211392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 2114efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << RegShiftedImm.SrcReg << " " 2115efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) 2116efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << " #" << RegShiftedImm.ShiftImm << ">"; 211792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 211821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 21197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 21207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 212121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 2122293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 2123293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 2124293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 212521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 212621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 212721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: { 21288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 21298d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 21305fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 21315fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 21327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 21337729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 21347729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 21358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 21368d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 21378d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 21388d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 21398d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 2140862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 2141862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OS << "<vector_list " << VectorList.Count << " * " 2142862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach << VectorList.RegNum << ">"; 2143862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 214498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case k_VectorListAllLanes: 214598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach OS << "<vector_list(all lanes) " << VectorList.Count << " * " 214698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach << VectorList.RegNum << ">"; 214798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 21487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case k_VectorListIndexed: 21497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OS << "<vector_list(lane " << VectorList.LaneIndex << ") " 21507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach << VectorList.Count << " * " << VectorList.RegNum << ">"; 21517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 215221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 2153fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 2154fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 2155460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 2156460a90540b045c102012da2492999557e6840526Jim Grosbach OS << "<vectorindex " << getVectorIndex() << ">"; 2157460a90540b045c102012da2492999557e6840526Jim Grosbach break; 2158fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 2159fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 21603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 21613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 21623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 21633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 21643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 21653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 21663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 21673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 216869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 216969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 21701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 2171bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 2172bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 2173bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 2174bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 21759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 2176e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 2177e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 21783a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 21791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 218018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 21817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 2182d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 2183590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string lowerCase = Tok.getString().lower(); 21840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 21850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 21860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 21870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 21880c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 21890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 21900c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 219140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach // Additional register name aliases for 'gas' compatibility. 219240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a1", ARM::R0) 219340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a2", ARM::R1) 219440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a3", ARM::R2) 219540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a4", ARM::R3) 219640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v1", ARM::R4) 219740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v2", ARM::R5) 219840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v3", ARM::R6) 219940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v4", ARM::R7) 220040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v5", ARM::R8) 220140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v6", ARM::R9) 220240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v7", ARM::R10) 220340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v8", ARM::R11) 220440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("sb", ARM::R9) 220540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("sl", ARM::R10) 220640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("fp", ARM::R11) 22070c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 22080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 22090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 221069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 2211b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 2212460a90540b045c102012da2492999557e6840526Jim Grosbach 2213e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 2214e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 2215d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 221619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 221719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 221819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 221919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 222019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 22210d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 22220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 22240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 22250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 22260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2227590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string lowerCase = Tok.getString().lower(); 22280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 2229af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach .Case("asl", ARM_AM::lsl) 22300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 22310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 22320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 22330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 22340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 22350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 22360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 22370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 223819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 22390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 2241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 2242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 2243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 2244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 2245eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 2246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 2247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 2248e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 2249e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 2250e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 2251e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 2252e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 2253e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 2254e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 2255e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 2256e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 2257e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 22588a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 22598a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar)) { 2260e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 2261e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 2262e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 226319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 226419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 226519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 226619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2267e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 2268e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 226919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 227019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 227119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 227219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2273e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 2274e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 2275e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 2276e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 2277e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 2278e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 2279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 228019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 228119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 2282e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2283e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 22841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 2285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 228619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 228719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 228819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 228919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 229019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 229119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 2292e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 229319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 229419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2295e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2296e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 229792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 229892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 2299af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 23000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 230192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 230292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 230392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 23040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 230519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 23060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 23070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 23080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 230950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 231050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 231150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 2312e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 2313e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 2314e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 231550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 23161355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2317e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 23181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 2319e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 232050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2321d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 232250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 2323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2324e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 2325e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 232650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 232750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 2328e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 2329460a90540b045c102012da2492999557e6840526Jim Grosbach return false; 2330460a90540b045c102012da2492999557e6840526Jim Grosbach } 2331460a90540b045c102012da2492999557e6840526Jim Grosbach 2332460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 2333460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 2334460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 2335460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 2336460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 2337460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 2338460a90540b045c102012da2492999557e6840526Jim Grosbach 2339460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 2340460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 2341460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2342460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2343460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 2344460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 2345460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2346460a90540b045c102012da2492999557e6840526Jim Grosbach } 2347460a90540b045c102012da2492999557e6840526Jim Grosbach 2348460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2349460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 2350460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 2351460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2352460a90540b045c102012da2492999557e6840526Jim Grosbach } 2353460a90540b045c102012da2492999557e6840526Jim Grosbach 2354460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 2355460a90540b045c102012da2492999557e6840526Jim Grosbach 2356460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 2357460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 2358460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 235999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 236099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 236150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2362a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2363a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2364fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 2365fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 2366fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 2367fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 2368e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 2369e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 2370e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 2371e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 2372e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 2373fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 2374e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2375e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 2376e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2377e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 2378e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 2379e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 2380e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 2381e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 2382e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 2383e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 2384e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 2385e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 2386e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 2387e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2388e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2389e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 2390fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 2391e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2392e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 2393e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2394e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 2395e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 2396e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 2397e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 2398e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 2399e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 2400e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2401e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2402e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2403e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2404e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2405e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2406e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 240789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 240889df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 240989df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 241089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 241189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 241289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 241389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 241489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 241589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 241689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 241789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 241889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 241989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 242089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 242189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 242289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 242389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 242489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 242589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 242689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 242789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 242889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 242989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 243089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 243189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 243289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 243389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 243489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 243589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 243689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 243789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 243889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 243989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 244089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 244189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 244243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2443fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2444fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2445f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 244643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2447e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 2448e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 2449c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2450c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2451e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2452fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2453e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 2454f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2455e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2456e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 2457fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2458f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2459fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 2460fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 246143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2462fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2463fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2464f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 246543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2466fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2467fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2468c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2469c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2470fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2471fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2472fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 2473f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2474fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2475fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2476fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2477f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2478e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2479e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 24809b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 24819b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}' 24829b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 24839b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 24849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc S = Parser.getTok().getLoc(); 24859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 24869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // If this isn't a '{', this isn't a coprocessor immediate operand. 24879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 24889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_NoMatch; 24899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '{' 24909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 24919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCExpr *Expr; 24929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 24939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (getParser().ParseExpression(Expr)) { 24949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "illegal expression"); 24959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 24969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 24979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 24989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 24999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 25009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 25019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 25029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach int Val = CE->getValue(); 25039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 25049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // Check for and consume the closing '}' 25059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 25069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 25079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc E = Parser.getTok().getLoc(); 25089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '}' 25099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 25109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 25119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_Success; 25129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach} 25139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 2514d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 2515d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 2516d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 2517d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 2518d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 2519d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 2520d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 2521d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2522d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 2523d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 2524d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 2525d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2526d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2527d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2528d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2529d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2530d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2531d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2532d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2533d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2534d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 2535d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2536ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register. 2537ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) { 2538ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach switch (QReg) { 2539ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach default: llvm_unreachable("expected a Q register!"); 2540ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q0: return ARM::D0; 2541ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q1: return ARM::D2; 2542ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q2: return ARM::D4; 2543ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q3: return ARM::D6; 2544ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q4: return ARM::D8; 2545ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q5: return ARM::D10; 2546ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q6: return ARM::D12; 2547ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q7: return ARM::D14; 2548ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q8: return ARM::D16; 254925e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach case ARM::Q9: return ARM::D18; 2550ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q10: return ARM::D20; 2551ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q11: return ARM::D22; 2552ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q12: return ARM::D24; 2553ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q13: return ARM::D26; 2554ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q14: return ARM::D28; 2555ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q15: return ARM::D30; 2556ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 2557ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach} 2558ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach 2559d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 256050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 25611355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 256218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 2563a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 2564e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 2565d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 2566d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 256716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2568d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 2569d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 2570d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 2571d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 2572d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 2573d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2574ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 2575ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // space for that many. 2576ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2577ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach 2578ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2579ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2580ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Reg = getDRegFromQReg(Reg); 2581ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2582ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach ++Reg; 2583ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 25841a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCRegisterClass *RC; 2585d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2586d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2587d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2588d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2589d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2590d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2591d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 2592d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2593e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 2594ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Store the register. 2595d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2596d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2597d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 2598d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 2599d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 2600d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2601d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2602d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2603e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.Lex(); // Eat the minus. 2604d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2605d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 2606d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2607d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2608ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2609ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 2610ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach EndReg = getDRegFromQReg(EndReg) + 1; 2611d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2612d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2613d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2614d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2615d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2616d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2617d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2618d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2619d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2620d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2621d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2622d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2623d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2624d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2625d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2626d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2627d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2628d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2629d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2630d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2631d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2632a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach const AsmToken RegTok = Parser.getTok(); 2633d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2634d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 26352d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2636ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2637ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach bool isQReg = false; 2638ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2639ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Reg = getDRegFromQReg(Reg); 2640ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach isQReg = true; 2641ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 2642d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2643d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2644d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2645d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2646a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg)) 2647d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2648a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) { 2649a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach Warning(RegLoc, "duplicated register (" + RegTok.getString() + 2650a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach ") in register list"); 2651a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach continue; 2652a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach } 2653d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2654d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2655d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2656d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2657d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2658d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2659d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2660ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (isQReg) 2661ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc)); 2662d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2663d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2664d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2665d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2666d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2667d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2668e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 266927debd60a152d39e421c57bce511f16d8439a670Jim Grosbach // Push the register list operand. 267050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 267127debd60a152d39e421c57bce511f16d8439a670Jim Grosbach 267227debd60a152d39e421c57bce511f16d8439a670Jim Grosbach // The ARM system instruction variants for LDM/STM have a '^' token here. 267327debd60a152d39e421c57bce511f16d8439a670Jim Grosbach if (Parser.getTok().is(AsmToken::Caret)) { 267427debd60a152d39e421c57bce511f16d8439a670Jim Grosbach Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc())); 267527debd60a152d39e421c57bce511f16d8439a670Jim Grosbach Parser.Lex(); // Eat '^' token. 267627debd60a152d39e421c57bce511f16d8439a670Jim Grosbach } 267727debd60a152d39e421c57bce511f16d8439a670Jim Grosbach 267850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2679d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2680d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 268198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists. 268298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 26837636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) { 26847636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Index = 0; // Always return a defined index value. 268598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 268698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Parser.Lex(); // Eat the '['. 268798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Parser.getTok().is(AsmToken::RBrac)) { 268898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // "Dn[]" is the 'all lanes' syntax. 268998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach LaneKind = AllLanes; 269098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Parser.Lex(); // Eat the ']'. 269198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_Success; 269298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 26937636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (Parser.getTok().is(AsmToken::Integer)) { 26947636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach int64_t Val = Parser.getTok().getIntVal(); 26957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // Make this range check context sensitive for .8, .16, .32. 26967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (Val < 0 && Val > 7) 26977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Error(Parser.getTok().getLoc(), "lane index out of range"); 26987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Index = Val; 26997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach LaneKind = IndexedLane; 27007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Parser.Lex(); // Eat the token; 27017636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 27027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Error(Parser.getTok().getLoc(), "']' expected"); 27037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Parser.Lex(); // Eat the ']'. 27047636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return MatchOperand_Success; 27057636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 27067636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Error(Parser.getTok().getLoc(), "lane index must be empty or an integer"); 270798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 270898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 270998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach LaneKind = NoLanes; 271098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_Success; 271198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach} 271298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 2713862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list 2714862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2715862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 271698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy LaneKind; 27177636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned LaneIndex; 27185c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach SMLoc S = Parser.getTok().getLoc(); 27195c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // As an extension (to match gas), support a plain D register or Q register 27205c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // (without encosing curly braces) as a single or double entry list, 27215c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // respectively. 27225c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) { 27235c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach int Reg = tryParseRegister(); 27245c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Reg == -1) 27255c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_NoMatch; 27265c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 27275c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) { 27287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex); 272998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Res != MatchOperand_Success) 273098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Res; 273198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 273298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 273398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind!"); 273498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 273598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 273698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, S, E)); 273798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 273898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 273998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 274098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, S, E)); 274198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 27427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 27437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1, 27447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach LaneIndex, S,E)); 27457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 274698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 27475c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_Success; 27485c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 27495c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 27505c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Reg = getDRegFromQReg(Reg); 27517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex); 275298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Res != MatchOperand_Success) 275398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Res; 275498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 275598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 275698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind!"); 275798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 275898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 275998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, S, E)); 276098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 276198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 276298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 276398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, S, E)); 276498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 27657636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 27667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2, 27677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach LaneIndex, S,E)); 27687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 276998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 27705c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_Success; 27715c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 27725c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Error(S, "vector register expected"); 27735c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_ParseFail; 27745c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 27755c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach 27765c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 2777862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_NoMatch; 2778862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2779862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '{' token. 2780862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 2781862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2782862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int Reg = tryParseRegister(); 2783862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2784862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2785862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2786862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2787862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count = 1; 2788c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach unsigned FirstReg = Reg; 2789c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // The list is of D registers, but we also allow Q regs and just interpret 2790c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // them as the two D sub-registers. 2791c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2792c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach FirstReg = Reg = getDRegFromQReg(Reg); 2793c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Reg; 2794c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Count; 2795c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 27967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success) 279798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 2798c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach 2799e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2800e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2801e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2802e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.Lex(); // Eat the minus. 2803e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2804e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach int EndReg = tryParseRegister(); 2805e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (EndReg == -1) { 2806e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "register expected"); 2807e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2808e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 2809e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2810e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 2811e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach EndReg = getDRegFromQReg(EndReg) + 1; 2812e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // If the register is the same as the start reg, there's nothing 2813e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // more to do. 2814e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Reg == EndReg) 2815e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach continue; 2816e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // The register must be in the same register class as the first. 2817e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) { 2818e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "invalid register in register list"); 2819e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2820e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 2821e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Ranges must go from low to high. 2822e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Reg > EndReg) { 2823e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "bad range in register list"); 2824e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2825e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 282698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 282798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 28287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 28297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 283098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 28317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 283298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 283398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 283498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 283598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach EndLoc = Parser.getTok().getLoc(); 2836e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach 2837e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Add all the registers in the range to the register list. 2838e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Count += EndReg - Reg; 2839e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Reg = EndReg; 2840e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach continue; 2841e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 2842862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat the comma. 2843862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach RegLoc = Parser.getTok().getLoc(); 2844862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int OldReg = Reg; 2845862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Reg = tryParseRegister(); 2846862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2847862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2848862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2849862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2850c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // vector register lists must be contiguous. 2851862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // It's OK to use the enumeration values directly here rather, as the 2852862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // VFP register classes have the enum sorted properly. 2853c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // 2854c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // The list is of D registers, but we also allow Q regs and just interpret 2855c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // them as the two D sub-registers. 2856c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2857c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Reg = getDRegFromQReg(Reg); 2858c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (Reg != OldReg + 1) { 2859c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Error(RegLoc, "non-contiguous register range"); 2860c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach return MatchOperand_ParseFail; 2861c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 2862c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Reg; 2863c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Count += 2; 286498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 286598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 28667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 286798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 28687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 286998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 28707636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 287198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 287298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 287398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 2874c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach continue; 2875c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 2876c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // Normal D register. Just check that it's contiguous and keep going. 2877862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg != OldReg + 1) { 2878862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "non-contiguous register range"); 2879862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2880862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2881862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ++Count; 288298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 288398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 28847636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 288598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 28867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 288798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 28887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 288998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 289098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 289198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 2892862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2893862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2894862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2895862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) { 2896862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(E, "'}' expected"); 2897862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2898862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2899862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '}' token. 2900862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 290198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 290298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 290398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind in register list."); 290498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 290598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E)); 290698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 290798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 290898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count, 290998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach S, E)); 291098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 29117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 29127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count, 29137636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach LaneIndex, S, E)); 29147636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 291598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 2916862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_Success; 2917862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach} 2918862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 291943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2920f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 292143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2922706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2923706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2924706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2925706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 2926706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2927706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2928706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 2929706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 2930032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 2931706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 2932032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 2933706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 2934706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 2935032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 2936706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 2937032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 2938706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 2939706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 2940706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 2941706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2942706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 2943f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2944706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2945706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2946706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2947f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2948706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 2949706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 295043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2951a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 295243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2953a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2954a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2955a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2956a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 2957a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 29582dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // An iflags string of "none" is interpreted to mean that none of the AIF 29592dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // bits are set. Not a terribly useful instruction, but a valid encoding. 2960a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 29612dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (IFlagsStr != "none") { 29622dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 29632dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 29642dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("a", ARM_PROC::A) 29652dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("i", ARM_PROC::I) 29662dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("f", ARM_PROC::F) 29672dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Default(~0U); 29682dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 29692dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // If some specific iflag is already set, it means that some letter is 29702dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // present more than once, this is not acceptable. 29712dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (Flag == ~0U || (IFlags & Flag)) 29722dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson return MatchOperand_NoMatch; 29732dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 29742dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson IFlags |= Flag; 29752dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson } 2976a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2977a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2978a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2979a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2980a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 2981584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 2982584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 298343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2984584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 298543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2986584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2987584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2988584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2989584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 2990584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2991acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 2992acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 2993acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2994acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 2995acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 2996acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 2997acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 2998acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 2999acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 3000acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 3001acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 3002acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 3003acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 3004acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 3005acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 3006acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 3007acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 3008acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 3009acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3010acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 3011acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 3012acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3013acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 3014acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 3015acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 3016acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3017acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 3018acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 3019acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 3020acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 3021acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3022584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 3023584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 3024584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 3025590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string SpecReg = Mask.slice(Start, Next).lower(); 3026584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 3027584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 3028584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3029584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 3030584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 3031584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 3032584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 3033584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3034584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 3035584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 3036b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 3037584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 3038584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 3039584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 3040584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 30414b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 3042584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 3043584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3044584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 3045bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 30464b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 3047584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 304856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 304956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 3050584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 3051584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 3052584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 3053584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 3054584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 3055584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 3056584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 3057584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3058584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 3059584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 3060584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 3061584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3062584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 3063584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 3064584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 3065584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3066584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 30677784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // Special register without flags is NOT equivalent to "fc" flags. 30687784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // NOTE: This is a divergence from gas' behavior. Uncommenting the following 30697784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // two lines would enable gas compatibility at the expense of breaking 30707784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // round-tripping. 30717784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // 30727784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // if (!FlagsVal) 30737784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // FlagsVal = 0x9; 3074584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3075584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 3076584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 3077584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 3078584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3079584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 3080584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 3081584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 3082a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 3083a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3084f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3085f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 3086f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 3087f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 3088f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3089f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 3090f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3091f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3092f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 3093590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string LowerOp = Op.lower(); 3094590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string UpperOp = Op.upper(); 3095f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 3096f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 3097f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3098f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3099f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 3100f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3101f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 31028a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 31038a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3104f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3105f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3106f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3107f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 3108f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3109f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 3110f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 3111f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 3112f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 3113f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3114f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3115f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 3116f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 3117f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 3118f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3119f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3120f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 3121f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 3122f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 3123f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3124f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3125f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3126f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 3127f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3128f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 3129f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 3130f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3131c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3132c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3133c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 3134c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 3135c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3136c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 3137c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 3138c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 3139c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 3140c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 3141c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 3142c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 3143c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 3144c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 3145c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 3146c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 3147c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 3148c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 3149c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 3150c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 3151c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 3152c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 3153c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 3154c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 3155580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 3156580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 3157580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 3158580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 3159580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 3160580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3161580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3162580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 3163580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 3164580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3165580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 3166580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3167580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3168580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 3169580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 3170580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 3171580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 3172580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 3173580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 3174580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 3175580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 3176580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3177580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3178580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 3179580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3180580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 31818a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 31828a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3183580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3184580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3185580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3186580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 3187580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3188580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 3189580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 3190580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 3191580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 3192580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3193580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3194580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 3195580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 3196580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 3197580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3198580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3199580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3200580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 3201580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 3202580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 3203580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 3204580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 3205580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3206580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 32070afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 32080afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 32090afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 32100afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 32110afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 3212580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 3213580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 3214580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 3215580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 3216580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 3217580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3218580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3219580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3220580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3221580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 3222580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 3223580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3224580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 3225580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 3226580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 32277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 32287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 32297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 32307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 32317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 32337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 3234326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 3235326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 32367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 3237326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 3238326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 32397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 32407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 32428a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 32438a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 32447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 32457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 32467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 32477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 32487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 32507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 32517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 32527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 32537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 32547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 32557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 32567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 32577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 32587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 32597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 32607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 32627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 32637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 32647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 32657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 32667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 32677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 32687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 32697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 32717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 32727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 32747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 32757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 3276293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3277293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3278293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 3279293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 32808a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 32818a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3282293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3283293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3284293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3285293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 3286293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3287293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 3288293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3289293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 3290293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 3291293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3292293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 3294293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 3295293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 3296293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3297293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3298293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3299293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 3300293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 3301293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 3302293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 3303293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3304293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3305293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 3306293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3307293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 3308293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 3309293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 3310293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3311293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3312293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 33138a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 33148a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3315293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3316293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3317293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3318293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 3319293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3320293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 3321293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 3322293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 3323293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3324293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3325293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 3326293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 3327293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 3328293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3329293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3330293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3331293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 3332293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 3333293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 3334293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 3335293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3336293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3337293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 3338293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3339293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 3340293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3341293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 3342293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 3343293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 33447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 33457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 33467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 3347f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 3348f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 3349f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 33507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 33517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 33527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 33537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 33547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 33557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 33567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 335716578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 33587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 33597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 33607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 33617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 33627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 33637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 336416578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 33657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 33667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 33677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 33687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 33697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 33707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 33717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 33727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 33737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 33747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 33757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 33767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3377f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 3378f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 33790d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 33800d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 33810d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 33820d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 33830d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 3384f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 3385f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 3386f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 33877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 33887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 33897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 33907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3391251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3392251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3393251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 3394251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 3395251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 3396251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 3397251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 3398251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 3399251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 3400251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3401251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 3402251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 3403251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 3404251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 3405251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 3406251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3407251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 34088a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 34098a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar)) { 3410251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 3411251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 3412251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 3413251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 3414251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 3415251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 3416251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3417251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 3418251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 3419251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 3420251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3421251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3422251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 3423251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 3424251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 3425251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 3426251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 3427251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3428251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 3429251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 3430251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3431251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3432251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3433251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3434251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3435251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 3436251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 3437251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 3438251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 3439251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 3440251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 3441251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 3442251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 3443251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 3444251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 3445251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3446251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 3447251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 3448251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 3449251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 3450251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 3451251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 3452251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3453251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3454251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3455251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3456251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 3457251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 3458251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3459251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3460251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 3461251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3462a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 3463a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3464a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3465a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3466a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 3467a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3468a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3469a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3470a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3471a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3472a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3473a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3474a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3475a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3476a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3477a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3478a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3479a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3480a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 3481a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3482a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3483a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3484a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 3485a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3486a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3487a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3488a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3489a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3490a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3491a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3492a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3493a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3494a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3495a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3496a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3497a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3498eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3499eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3500eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3501eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 3502eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3503eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3504eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3505eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3506eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 3507eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3508eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3509eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3510eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3511eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 3512eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 3513eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3514ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3515ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3516ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3517ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 3518ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3519ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3520ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 3521ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3522ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3523ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3524ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3525ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 3526ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 3527ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 35281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3529ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3530ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3531ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 35321355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3533ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3534ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3535ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 3536ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3537ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3538ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 35397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3540ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3541ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3542ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3543ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 35449ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 35459ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 35469ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 35479ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 35489ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 35499ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 35509ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 35519ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 35529ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 35539ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 35549ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 35559ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 35569ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 35579ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 35589ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 35599ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 35609ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 3561548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 3562548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3563548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3564548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 3565548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 3566548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3567548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 3568548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3569548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3570548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 3571548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3572548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 3573548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 3574548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 35751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3576ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3577ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3578ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 35791355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3580ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3581ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3582ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3583548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3584548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3585548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 35867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 35877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 35887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 35897b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 35907b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 35917b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 35927b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 35937b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 35947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 35957b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 35967b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 35977b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 35987b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 35997b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 36007b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 36017b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 36027b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 36037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 36047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 36057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 36067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 36077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 36087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 36097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 36117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 36127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 36137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 36147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 36157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 36167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 36177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3618ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3619ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3620ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3621ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 36227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 3623ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3624ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3625ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 36267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 36277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 36287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3629aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3630ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3631ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 36327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 36337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 36347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 36357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 36367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 36377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 36387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 36397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 3640aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 36417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 36427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 36437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 36447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 36457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 36467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 36477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 36487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 36497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 36507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 36517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 36527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 36537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 36547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 36557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3656ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3657ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3658ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3659ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 36607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 3661ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3662ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3663ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 36647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 36657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3666ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3667ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 36687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 36707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 36717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 36727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 36737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 36747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3675ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3676ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3677ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3678ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 36792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 36802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 36812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 36822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 36832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 36842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 36852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 36862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 36872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 36882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 36892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 36902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 36912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 36922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 36932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 36942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 36952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 36962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 369714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 369814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 369914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 370014605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 370114605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 370214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 370314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 370414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 370514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 370614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 370714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 370814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 370914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 371014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 371114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 371214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 371314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 371414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 3715623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 3716623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3717623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3718623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 3719623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 3720623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3721623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3722623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 3723623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3724623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 3725623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3726623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 3727623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 3728623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 372988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 373088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 373188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 373288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 373388ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 373488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 373588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 373688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 373788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 37387a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 37397a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 37407a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 37417a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 374288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 37437a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 374488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 374588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 374688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 374788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 37481b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach // If we have a three-operand form, make sure to set Rn to be the operand 37491b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach // that isn't the same as Rd. 37501b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach unsigned RegOp = 4; 37511b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach if (Operands.size() == 6 && 37521b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[4])->getReg() == 37531b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[3])->getReg()) 37541b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach RegOp = 5; 37551b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1); 37561b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach Inst.addOperand(Inst.getOperand(0)); 375788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 375888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 375988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 376088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 3761623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 376212431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser:: 376312431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode, 376412431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 376512431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vd 37666029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 376712431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Create a writeback register dummy placeholder. 376812431329d617064d6e72dd040a58c1635cc261abJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 376912431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vn 377012431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 377112431329d617064d6e72dd040a58c1635cc261abJim Grosbach // pred 377212431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 377312431329d617064d6e72dd040a58c1635cc261abJim Grosbach return true; 377412431329d617064d6e72dd040a58c1635cc261abJim Grosbach} 377512431329d617064d6e72dd040a58c1635cc261abJim Grosbach 377612431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser:: 377712431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode, 377812431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 377912431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vd 37806029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 378112431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Create a writeback register dummy placeholder. 378212431329d617064d6e72dd040a58c1635cc261abJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 378312431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vn 378412431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 378512431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vm 378612431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 378712431329d617064d6e72dd040a58c1635cc261abJim Grosbach // pred 378812431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 378912431329d617064d6e72dd040a58c1635cc261abJim Grosbach return true; 379012431329d617064d6e72dd040a58c1635cc261abJim Grosbach} 379112431329d617064d6e72dd040a58c1635cc261abJim Grosbach 37924334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser:: 37934334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode, 37944334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 37954334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Create a writeback register dummy placeholder. 37964334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 37974334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vn 37984334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 37994334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vt 38006029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 38014334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // pred 38024334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 38034334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach return true; 38044334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach} 38054334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach 38064334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser:: 38074334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode, 38084334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 38094334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Create a writeback register dummy placeholder. 38104334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 38114334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vn 38124334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 38134334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vm 38144334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 38154334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vt 38166029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 38174334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // pred 38184334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 38194334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach return true; 38204334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach} 38214334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach 3822e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 38239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 382450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 38257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3826762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 382718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3828a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 3829762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3830b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 3831a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 383218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 38331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 38347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 38357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 3836a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 38370571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 38380571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 38390571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 38407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 38410571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 38427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 3843762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 3844b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 3845a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 38467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 384757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 0, 0, false, S, E)); 384803f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 3849fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3850fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 3851fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3852fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3853fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 3854fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 3855fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 38567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 38577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 385850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 38597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 38607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 386150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 386257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a ':', it's an alignment specifier. 386357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Colon)) { 386457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the ':'. 386557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 386657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 386757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCExpr *Expr; 386857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (getParser().ParseExpression(Expr)) 386957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return true; 387057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 387157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // The expression has to be a constant. Memory references with relocations 387257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // don't come through here, as they use the <label> forms of the relevant 387357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // instructions. 387457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 387557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!CE) 387657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error (E, "constant expression expected"); 387757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 387857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Align = 0; 387957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach switch (CE->getValue()) { 388057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach default: 388157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "alignment specifier must be 64, 128, or 256 bits"); 388257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 64: Align = 8; break; 388357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 128: Align = 16; break; 388457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 256: Align = 32; break; 388557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 388657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 388757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Now we should have the closing ']' 388857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 388957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 389057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "']' expected"); 389157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat right bracket token. 389257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 389357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Don't worry about range checking the value here. That's handled by 389457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // the is*() predicates. 389557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 389657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, Align, 389757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 389857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 389957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 390057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // operand. 390157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 390257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 390357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the '!'. 390457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 390557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 390657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return false; 390757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 390857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 390957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a '#', it's an immediate offset, else assume it's a register 39106cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach // offset. Be friendly and also accept a plain integer (without a leading 39116cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach // hash) for gas compatibility. 39126cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 39138a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar) || 39146cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach Parser.getTok().is(AsmToken::Integer)) { 39158a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Integer)) 39166cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach Parser.Lex(); // Eat the '#'. 39177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 391850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 39190da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 39207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 39217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 39227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 392305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 39247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 39257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 39267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 39277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 39287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 39297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 39307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 39310da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 39320da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 39330da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 39340da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 39350da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 39367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 39377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 39387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 39397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 39407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 394105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 39427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 39437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 39447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 394557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, 0, 394657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 3947a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 39487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 39497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 39507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 39517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 39527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 3953762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 39547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 39557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 39569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 3957d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 39587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 39597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 39607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 39617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 39627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 39637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 39647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 39657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 39667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 39679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 39687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 39697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 39707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 39717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 39727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 39737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 39747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 39750d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 39767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 39777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 39780d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 39797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 39809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 398116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 39827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 39837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 39847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 39857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 39867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 39877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 39887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 398957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ShiftType, ShiftImm, 0, isNegative, 39907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 39917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3992f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3993f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 3994f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3995f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3996f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 3997f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 39989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 39999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 40009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 40019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 40027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 4003a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 4004a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 40057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 40067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 40077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 40087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 400918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4010a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 4011a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 401238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 4013af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL" || 4014af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach ShiftName == "asl" || ShiftName == "ASL") 40150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 4016a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 40170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 4018a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 40190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 4020a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 40210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 4022a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 40230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 4024a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 40257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 4026b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 4027a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 40297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 40307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 40317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 40327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 40337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 40348a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (HashTok.isNot(AsmToken::Hash) && 40358a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach HashTok.isNot(AsmToken::Dollar)) 40367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 40377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 40389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 40397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 40407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 40417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 40427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 40437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 40447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 40457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 40467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 40477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 40487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 40497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 40507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 40517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 40527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 40537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 40547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 4055a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4056a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 4057a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 4058a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40599d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 40609d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 40619d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 40629d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 40639d39036f62674606565217a10db28171b9594bc7Jim Grosbach 40648a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 40658a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) 40669d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 40670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 40680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Disambiguate the VMOV forms that can accept an FP immediate. 40690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <sreg>, #imm 40700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f64 <dreg>, #imm 40710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <dreg>, #imm @ vector f32x2 40720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <qreg>, #imm @ vector f32x4 40730e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // 40740e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // There are also the NEON VMOV instructions which expect an 40750e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // integer constant. Make sure we don't try to parse an FPImm 40760e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // for these: 40770e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.i{8|16|32|64} <dreg|qreg>, #imm 40780e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]); 40790e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!TyOp->isToken() || (TyOp->getToken() != ".f32" && 40800e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach TyOp->getToken() != ".f64")) 40810e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return MatchOperand_NoMatch; 40820e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 40839d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 40849d39036f62674606565217a10db28171b9594bc7Jim Grosbach 40859d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 40869d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 40879d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 40889d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 40899d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 40909d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 40919d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 40929d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 40939d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 40949d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 40959d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 40969d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 40979d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 40989d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 40999d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 41009d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 41019d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 41029d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 41039d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 41049d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 41059d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 41069d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 41079d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 41089d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 41099d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 41109d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 41119d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 41129d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 41139d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 41149d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 41159d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 41169d39036f62674606565217a10db28171b9594bc7Jim Grosbach 41179d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 41189d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 41199d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 41209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 41219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 41221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4123fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 4124762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 4125fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 4126fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 4127fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 4128f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 4129f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 4130fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 4131f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 4132f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 4133f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 4134f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 4135f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 4136fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 4137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 4138146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 4139146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 414050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 414119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 41425cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 41431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 414450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 41450d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 414619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 41470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 414819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 414919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 41505cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 41515cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 41525cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 41535cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 41545cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 41555cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 4156e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 4157e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 4158e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 415919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 4160758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach case AsmToken::LParen: // parenthesized expressions like (_strcmp-4) 416167b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 41626284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach case AsmToken::String: // quoted label names. 416367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 4164515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 4165515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 4166515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 4167762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 4168515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 416950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 4170762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 417150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 417250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 417350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 4174a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 41751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 4176d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 41771355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 41788a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach case AsmToken::Dollar: 417963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 4180079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 4181079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 4182762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 4183b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 418463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 4185515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 4186515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 418750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 418863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 4189ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach if (CE) { 4190ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach int32_t Val = CE->getValue(); 4191ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach if (isNegative && Val == 0) 4192ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 419363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 4194762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 419550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 419650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 419763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 41989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 41999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 42007597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 42017597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 42027597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 42031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 42049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42067597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 42077597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 42089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42107597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 42117597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 42129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 42137597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 42149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 42159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 4216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4217a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 4218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 42191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 42207597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 42211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 42227597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 42239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 42258a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 42269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 42279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 42299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 42309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 42329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 42349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 42357597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 42369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 42377597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 42389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 42399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 42409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 42429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 42439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 42459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 42469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 42489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 42499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 42509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 42519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 4252352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 4253352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 4254352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 4255badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 425689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 42571355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 42585f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 42595f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 426089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 426189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 4262352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 4263352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 4264a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 4265352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 4266badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 4267352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 4268352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 42695f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 42705f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 42715f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 42725f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 42735f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 42745f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 42755f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 42765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 4277352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 4278badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 42793f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 42803f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 4281ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 428271725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 428304d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 42842f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 42853f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 42863f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 42873f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 42883f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 42893f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 42903f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 42913f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 42923f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 42933f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 42943f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 42953f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 42963f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 42973f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 42983f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 42993f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 43003f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 43013f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 43023f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 43033f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 43043f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 43053f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 43063f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 43073f00e317064560ad11168d22030416d853829f6eJim Grosbach } 430852925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 4309345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4310352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 4311352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 4312352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 431300f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 43145f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 43155f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 43165f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 431767ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" || 431848171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" || 4319f10154010ec01a6965f86e8c136db79732c92eeeJim Grosbach Mnemonic == "fsts" || 4320e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 4321352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 4322352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 4323352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 4324352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 4325a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 4326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 4327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 4328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 4329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 4330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 4331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 4332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 4333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 4334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 4335a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 4336a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 4337a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4338a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4339a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 434089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 434189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 434289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 434389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 434489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 434589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4346352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 4347352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 43483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 43493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 43503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 43513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 43523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 4353fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 43541355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 4355fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 4356eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 4357eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 43583443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 4359eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 4360d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 4361eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 4362d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 43633443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 4364d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 4365d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 4366eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 4367fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 4368eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 43693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 4370eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 4371eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 4372eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 4373eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 4374ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 4375ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 43760780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 43772bd0118472de352745a2e038245fab4974f7c87eJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" || 43782bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "ldc2" || Mnemonic == "ldc2l" || 43792bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) || 43804af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 43814af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 43821ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 43833771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 4384fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 43853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 4386fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 4387fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 4388fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 438963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 4390fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 4391fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 4392badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 4393badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 4394d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 4395d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 439620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 439720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 4398d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 4399d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 4400d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 4401d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 4402d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 4403d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 4404d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 4405d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 4406d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 44078adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 4408d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 4409d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 4410d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 4411d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 44123912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 44133912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 44143912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 44153912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 44163912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 44173912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 44183912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 44193912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 442072f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 442120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 442220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 442320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 4424f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 4425f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 4426f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 442772f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 442872f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 442972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 443020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 443120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 443220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 443372f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 4434f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 4435f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 443620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 443720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 443820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 4439f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 4440f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 444120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 444220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 444320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 444420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 444520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 444620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 444720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 444820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 444920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 445020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 445120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 445220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 445320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 445420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 445520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 445664944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 445720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 445820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 445920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 446020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 446120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 446220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 446320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 446420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 446520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 446664944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 446764944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 446864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 446964944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 447064944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 447164944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 447264944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 447364944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 447464944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 447564944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 447664944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 447764944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 447864944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 447964944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 44801de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) || 448164944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 448264944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 448364944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 448464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 448564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 448664944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 448764944f48a1164c02c15ca423a53919682a89074cJim Grosbach 44887f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // Also check the 'mul' syntax variant that doesn't specify an explicit 44897f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // destination register. 44907f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 && 44917f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 44927f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 44937f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 44947f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // If the registers aren't low regs or the cc_out operand is zero 44957f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 44967f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // remove the cc_out operand. 44977f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 44987f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 44997f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach !inITBlock())) 45007f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach return true; 45017f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach 450264944f48a1164c02c15ca423a53919682a89074cJim Grosbach 450320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 4504f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 4505f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 4506f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 4507f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 4508f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 4509f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 4510f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 451172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 451272f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 451372f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 451472f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 45153912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 4516d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 4517d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 4518d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 45197aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) { 45207aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" || 45217aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" || 45227aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" || 45237aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" || 45247aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" || 45257aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".f" || Tok == ".d"; 45267aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach} 45277aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 45287aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class 45297aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be 45307aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now. 45317aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) { 45327aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm"); 45337aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach} 45347aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 453521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features); 4536badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 4537badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 4538badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 453921d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // Apply mnemonic aliases before doing anything else, as the destination 454021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // mnemnonic may include suffices and we want to handle them normally. 454121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // The generic tblgen'erated code does this later, at the start of 454221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // MatchInstructionImpl(), but that's too late for aliases that include 454321d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // any sort of suffix. 454421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach unsigned AvailableFeatures = getAvailableFeatures(); 454521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach applyMnemonicAliases(Name, AvailableFeatures); 454621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach 4547badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 4548badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 4549ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 4550badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 4551352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 4552352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 4553a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 4554352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 455589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 45561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 455789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 4558badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 45590c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 45600c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 45610c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 45620c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 45630c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 45640c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 4565ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 4566ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 456789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 456889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 456989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 457089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 457189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 457289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 4573f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 4574f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 4575f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 4576f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 4577f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 457889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 457989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 458089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 458189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 458289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 4583f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 458489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 458589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 458689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 458789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 458889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4589f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 459089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 459189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4592ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 4593ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 45949717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 45953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 45963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 45973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 45983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 45993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 46003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 46013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 46023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 46031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 46043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 460533c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 460633c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 460733c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 460833c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 4609ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 461033c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 461133c16a27370939de39679245c3dff72383c210bdJim Grosbach } 4612c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 4613c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 4614c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 4615c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 4616c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 4617c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 4618c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 461933c16a27370939de39679245c3dff72383c210bdJim Grosbach 46203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 4621f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 4622f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 46233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 4624f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 4625f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 46263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 46273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 46283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 4629f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 4630f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 46313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 4632f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 4633badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 4634345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4635a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 4636a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 4637a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 4638a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 4639a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 4640a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4641a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 4642345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 46435747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 46445747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 46455747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 4646a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 4647a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 46487aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach // Some NEON instructions have an optional datatype suffix that is 46497aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach // completely ignored. Check for that. 46507aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach if (isDataTypeToken(ExtraToken) && 46517aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken)) 46527aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach continue; 46537aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 465481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 465581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 465681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 465781d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 46585747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 46595747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 46605747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 46615747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 4662a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 46631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4664cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4665cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4666cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4667a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4668a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 4669b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 4670a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4671a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 46721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4673cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4674cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4675cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4676a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4677a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 467816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4679cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 4680186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach SMLoc Loc = getLexer().getLoc(); 4681cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4682186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach return Error(Loc, "unexpected token in argument list"); 4683cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4684146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 468534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 4686ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4687d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 4688d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 4689d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 469020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 469120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 469220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 469320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 469420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 4695ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4696ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 4697ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 4698ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 4699ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4700cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 4701cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 4702cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 470321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // a k_CondCode operand in the list. If we're trying to match the label 470421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // version, remove the k_CondCode operand here. 4705cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 4706cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 4707cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4708cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 4709cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 4710cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 4711857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 4712857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 4713857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 4714857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 4715857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 4716857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 4717857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4718857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4719857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4720857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 4721857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 4722857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 472368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 472468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 472568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 472668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 472768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 472868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 472968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 473068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 473168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 473268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 473368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4734857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 4735857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4736857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4737934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 473855b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach // end. Convert it to a token here. Take care not to convert those 473955b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach // that should hit the Thumb2 encoding. 4740934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 474155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 474255b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 4743934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4744934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4745934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 474655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach if (CE && CE->getValue() == 0 && 474755b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach (isThumbOne() || 4748d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach // The cc_out operand matches the IT block. 4749d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach ((inITBlock() != CarrySetting) && 4750d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach // Neither register operand is a high register. 475155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 4752d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){ 4753934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 4754934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4755934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 4756934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4757934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4758934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 47599898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 4760ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4761ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4762189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 4763aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 4764aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 4765aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 4766aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 4767aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 4768aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 4769aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 4770aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 4771aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 4772aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 4773aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 4774aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 4775aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 4776aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 4777aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 4778aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 4779aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 4780aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 478176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 478276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 478376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 478476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 478576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 478676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 478776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 478876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 478976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 479076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 479176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 4792f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 4793f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 4794f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 4795f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 47961a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[]; 4797f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 47981a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) { 4799f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 4800f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 4801f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4802189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 4803189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 4804189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 4805189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 48061a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 4807f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 4808f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 4809b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 4810b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 4811b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 4812b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 4813f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 4814f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 4815f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 4816f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 4817a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 4818f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 4819f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 4820f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 4821f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 4822f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 4823f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 4824f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 4825f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 4826f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 4827f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 4828f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 4829f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 4830f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 4831f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 4832f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 4833f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 4834f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 4835c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 4836f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 4837f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 483851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 483951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 4840f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 4841f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4842189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 48432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 48442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 48452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 4846189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 4847189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4848189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 4849189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4850189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 4851189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 4852189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 4853189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4854189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 485514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 485614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 485714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 485814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 485914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 486014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 486114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 486214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 486314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 486453642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 486553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 4866189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 4867189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4868189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4869189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 4870189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 487114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 4872189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 4873189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4874189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4875fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 4876fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 4877fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 4878fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 4879fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 4880fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 4881fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 4882fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 488300c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 4884fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 488593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 488676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 488776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 488876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 488976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 489076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 489193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 489293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 489393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 48947260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 48957260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 48967260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 4897aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 489876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 4899aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 4900aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 490193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 490276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 490393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 490493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 490576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 490676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 4907aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 49087260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 49097260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 49107260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 491193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 491293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 491393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 491476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 491576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 491676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 491776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 491876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 491976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 492076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 49215402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2, 49225402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // so only issue a diagnostic for thumb1. The instructions will be 49235402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // switched to the t2 encodings in processInstruction() if necessary. 49246dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 4925aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 49265402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) && 49275402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach !isThumbTwo()) 4928aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4929aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 49306dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 49316dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 49326dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 4933aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 49345402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) && 49355402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach !isThumbTwo()) 4936aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4937aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 49386dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 49396dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 49401e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 49411e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 49428213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 49431e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 49441e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 49451e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 49461e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 4947189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4948189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4949189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4950189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 4951189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 495284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbachstatic unsigned getRealVSTLNOpcode(unsigned Opc) { 495384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach switch(Opc) { 495484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach default: assert(0 && "unexpected opcode!"); 495584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_8: return ARM::VST1LNd8_UPD; 495684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P8: return ARM::VST1LNd8_UPD; 495784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I8: return ARM::VST1LNd8_UPD; 495884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S8: return ARM::VST1LNd8_UPD; 495984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U8: return ARM::VST1LNd8_UPD; 496084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_16: return ARM::VST1LNd16_UPD; 496184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P16: return ARM::VST1LNd16_UPD; 496284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I16: return ARM::VST1LNd16_UPD; 496384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S16: return ARM::VST1LNd16_UPD; 496484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U16: return ARM::VST1LNd16_UPD; 496584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_32: return ARM::VST1LNd32_UPD; 496684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F: return ARM::VST1LNd32_UPD; 496784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F32: return ARM::VST1LNd32_UPD; 496884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I32: return ARM::VST1LNd32_UPD; 496984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S32: return ARM::VST1LNd32_UPD; 497084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U32: return ARM::VST1LNd32_UPD; 497184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_8: return ARM::VST1LNd8_UPD; 497284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_P8: return ARM::VST1LNd8_UPD; 497384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I8: return ARM::VST1LNd8_UPD; 497484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S8: return ARM::VST1LNd8_UPD; 497584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U8: return ARM::VST1LNd8_UPD; 497684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_16: return ARM::VST1LNd16_UPD; 497784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_P16: return ARM::VST1LNd16_UPD; 497884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I16: return ARM::VST1LNd16_UPD; 497984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S16: return ARM::VST1LNd16_UPD; 498084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U16: return ARM::VST1LNd16_UPD; 498184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_32: return ARM::VST1LNd32_UPD; 498284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_F: return ARM::VST1LNd32_UPD; 498384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_F32: return ARM::VST1LNd32_UPD; 498484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I32: return ARM::VST1LNd32_UPD; 498584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S32: return ARM::VST1LNd32_UPD; 498684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U32: return ARM::VST1LNd32_UPD; 498784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_8: return ARM::VST1LNd8; 498884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_P8: return ARM::VST1LNd8; 498984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I8: return ARM::VST1LNd8; 499084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S8: return ARM::VST1LNd8; 499184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U8: return ARM::VST1LNd8; 499284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_16: return ARM::VST1LNd16; 499384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_P16: return ARM::VST1LNd16; 499484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I16: return ARM::VST1LNd16; 499584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S16: return ARM::VST1LNd16; 499684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U16: return ARM::VST1LNd16; 499784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_32: return ARM::VST1LNd32; 499884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_F: return ARM::VST1LNd32; 499984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_F32: return ARM::VST1LNd32; 500084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I32: return ARM::VST1LNd32; 500184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S32: return ARM::VST1LNd32; 500284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U32: return ARM::VST1LNd32; 500384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 500484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach} 500584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach 500684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbachstatic unsigned getRealVLDLNOpcode(unsigned Opc) { 50077636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach switch(Opc) { 50087636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach default: assert(0 && "unexpected opcode!"); 5009872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_8: return ARM::VLD1LNd8_UPD; 5010872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P8: return ARM::VLD1LNd8_UPD; 5011872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I8: return ARM::VLD1LNd8_UPD; 5012872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S8: return ARM::VLD1LNd8_UPD; 5013872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U8: return ARM::VLD1LNd8_UPD; 5014872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_16: return ARM::VLD1LNd16_UPD; 5015872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P16: return ARM::VLD1LNd16_UPD; 5016872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I16: return ARM::VLD1LNd16_UPD; 5017872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S16: return ARM::VLD1LNd16_UPD; 5018872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U16: return ARM::VLD1LNd16_UPD; 5019872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_32: return ARM::VLD1LNd32_UPD; 5020872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F: return ARM::VLD1LNd32_UPD; 5021872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F32: return ARM::VLD1LNd32_UPD; 5022872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I32: return ARM::VLD1LNd32_UPD; 5023872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S32: return ARM::VLD1LNd32_UPD; 5024872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U32: return ARM::VLD1LNd32_UPD; 5025872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_8: return ARM::VLD1LNd8_UPD; 5026872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_P8: return ARM::VLD1LNd8_UPD; 5027872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I8: return ARM::VLD1LNd8_UPD; 5028872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S8: return ARM::VLD1LNd8_UPD; 5029872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U8: return ARM::VLD1LNd8_UPD; 5030872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_16: return ARM::VLD1LNd16_UPD; 5031872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_P16: return ARM::VLD1LNd16_UPD; 5032872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I16: return ARM::VLD1LNd16_UPD; 5033872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S16: return ARM::VLD1LNd16_UPD; 5034872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U16: return ARM::VLD1LNd16_UPD; 5035872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_32: return ARM::VLD1LNd32_UPD; 5036872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_F: return ARM::VLD1LNd32_UPD; 5037872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_F32: return ARM::VLD1LNd32_UPD; 5038872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I32: return ARM::VLD1LNd32_UPD; 5039872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S32: return ARM::VLD1LNd32_UPD; 5040872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U32: return ARM::VLD1LNd32_UPD; 5041dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_8: return ARM::VLD1LNd8; 5042dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_P8: return ARM::VLD1LNd8; 5043dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I8: return ARM::VLD1LNd8; 5044dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S8: return ARM::VLD1LNd8; 5045dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U8: return ARM::VLD1LNd8; 5046872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_16: return ARM::VLD1LNd16; 5047872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_P16: return ARM::VLD1LNd16; 5048872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_I16: return ARM::VLD1LNd16; 5049872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_S16: return ARM::VLD1LNd16; 5050872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_U16: return ARM::VLD1LNd16; 5051dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_32: return ARM::VLD1LNd32; 5052dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_F: return ARM::VLD1LNd32; 5053dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_F32: return ARM::VLD1LNd32; 5054dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I32: return ARM::VLD1LNd32; 5055dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S32: return ARM::VLD1LNd32; 5056dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U32: return ARM::VLD1LNd32; 50577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 50587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach} 50597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 506083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser:: 5061f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 5062f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 5063f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 506484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Handle NEON VST1 complex aliases. 506584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_8: 506684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_P8: 506784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I8: 506884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S8: 506984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U8: 507084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_16: 507184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_P16: 507284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I16: 507384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S16: 507484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U16: 507584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_32: 507684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_F: 507784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_F32: 507884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I32: 507984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S32: 508084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U32: { 508184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 508284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 508384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 508484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode())); 508584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 508684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 508784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 508884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rm 508984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 509084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 509184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // CondCode 509284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 509384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 509484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 509584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 509684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_8: 509784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P8: 509884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I8: 509984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S8: 510084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U8: 510184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_16: 510284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P16: 510384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I16: 510484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S16: 510584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U16: 510684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_32: 510784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F: 510884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F32: 510984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I32: 511084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S32: 511184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U32: { 511284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 511384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 511484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 511584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode())); 511684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 511784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 511884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 511984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 512084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 512184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 512284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 512384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 512484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 512584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 512684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 512784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_8: 512884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_P8: 512984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I8: 513084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S8: 513184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U8: 513284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_16: 513384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_P16: 513484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I16: 513584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S16: 513684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U16: 513784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_32: 513884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_F: 513984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_F32: 514084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I32: 514184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S32: 514284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U32: { 514384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 514484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 514584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 514684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode())); 514784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 514884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 514984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 515084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 515184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 515284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 515384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 515484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 515584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 51567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // Handle NEON VLD1 complex aliases. 5157872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_8: 5158872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_P8: 5159872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I8: 5160872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S8: 5161872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U8: 5162872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_16: 5163872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_P16: 5164872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I16: 5165872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S16: 5166872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U16: 5167872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_32: 5168872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_F: 5169872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_F32: 5170872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I32: 5171872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S32: 5172872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U32: { 5173872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach MCInst TmpInst; 5174872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // Shuffle the operands around so the lane index operand is in the 5175872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // right place. 517684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode())); 5177872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 5178872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 5179872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 5180872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 5181872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rm 5182872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 5183872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 5184872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // CondCode 5185872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 5186872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach Inst = TmpInst; 5187872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach return true; 5188872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach } 5189872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_8: 5190872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P8: 5191872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I8: 5192872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S8: 5193872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U8: 5194872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_16: 5195872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P16: 5196872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I16: 5197872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S16: 5198872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U16: 5199872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_32: 5200872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F: 5201872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F32: 5202872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I32: 5203872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S32: 5204872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U32: { 5205872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach MCInst TmpInst; 5206872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // Shuffle the operands around so the lane index operand is in the 5207872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // right place. 520884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode())); 5209872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 5210872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 5211872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 5212872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 5213872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 5214872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 5215872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 5216872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 5217872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 5218872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach Inst = TmpInst; 5219872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach return true; 5220872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach } 5221dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_8: 5222dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_P8: 5223dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I8: 5224dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S8: 5225dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U8: 5226dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_16: 5227dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_P16: 5228dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I16: 5229dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S16: 5230dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U16: 5231dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_32: 5232dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_F: 5233dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_F32: 5234dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I32: 5235dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S32: 5236dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U32: { 52377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach MCInst TmpInst; 52387636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // Shuffle the operands around so the lane index operand is in the 52397636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // right place. 524084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode())); 52417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 52427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 52437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 52447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 52457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 52467636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 52477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 52487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst = TmpInst; 52497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return true; 52507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 525171810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach // Handle the MOV complex aliases. 525223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::ASRr: 525323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSRr: 525423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSLr: 525523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::RORr: { 525623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 525723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach switch(Inst.getOpcode()) { 525823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 525923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::ASRr: ShiftTy = ARM_AM::asr; break; 526023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSRr: ShiftTy = ARM_AM::lsr; break; 526123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSLr: ShiftTy = ARM_AM::lsl; break; 526223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::RORr: ShiftTy = ARM_AM::ror; break; 526323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach } 526423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach // A shift by zero is a plain MOVr, not a MOVsi. 526523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0); 526623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach MCInst TmpInst; 526723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.setOpcode(ARM::MOVsr); 526823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 526923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 527023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rm 527123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 527223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // CondCode 527323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 527423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // cc_out 527523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach Inst = TmpInst; 527623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach return true; 527723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach } 5278ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::ASRi: 5279ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSRi: 5280ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSLi: 5281ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::RORi: { 5282ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 5283ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach switch(Inst.getOpcode()) { 5284ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 5285ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::ASRi: ShiftTy = ARM_AM::asr; break; 5286ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSRi: ShiftTy = ARM_AM::lsr; break; 5287ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSLi: ShiftTy = ARM_AM::lsl; break; 5288ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::RORi: ShiftTy = ARM_AM::ror; break; 5289ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach } 5290ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach // A shift by zero is a plain MOVr, not a MOVsi. 529148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach unsigned Amt = Inst.getOperand(2).getImm(); 5292ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi; 5293ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt); 529471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach MCInst TmpInst; 5295ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach TmpInst.setOpcode(Opc); 529671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 529771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 5298ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (Opc == ARM::MOVsi) 5299ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 530071810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // CondCode 530171810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 530271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // cc_out 530371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach Inst = TmpInst; 530483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 530571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach } 530648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach case ARM::RRXi: { 530748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0); 530848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach MCInst TmpInst; 530948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.setOpcode(ARM::MOVsi); 531048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 531148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 531248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 531348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 531448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 531548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // cc_out 531648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach Inst = TmpInst; 531748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach return true; 531848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach } 53190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach case ARM::t2LDMIA_UPD: { 53200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // If this is a load of a single register, then we should use 53210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 53220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach if (Inst.getNumOperands() != 5) 53230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return false; 53240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach MCInst TmpInst; 53250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.setOpcode(ARM::t2LDR_POST); 53260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 53270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 53280352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 53290352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 53300352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 53310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 53320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach Inst = TmpInst; 53330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return true; 53340352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach } 53350352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach case ARM::t2STMDB_UPD: { 53360352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // If this is a store of a single register, then we should use 53370352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 53380352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach if (Inst.getNumOperands() != 5) 53390352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return false; 53400352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach MCInst TmpInst; 53410352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.setOpcode(ARM::t2STR_PRE); 53420352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 53430352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 53440352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 53450352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 53460352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 53470352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 53480352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach Inst = TmpInst; 53490352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return true; 53500352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach } 5351f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 5352f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 5353f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 5354f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 5355f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 5356f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 5357f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 5358f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 5359f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 5360f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 5361f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 5362f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 5363f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 5364f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5365f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 536683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 5367f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 5368f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 5369f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 5370f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 5371f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 5372f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 5373f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 5374f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 5375f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 5376f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 5377f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 5378f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 5379f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 5380f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 5381f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5382f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 5383f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 5384f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 5385da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach case ARM::t2ADDri12: 5386da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // If the immediate fits for encoding T3 (t2ADDri) and the generic "add" 5387da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // mnemonic was used (not "addw"), encoding T3 is preferred. 5388da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" || 5389da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 5390da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5391da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.setOpcode(ARM::t2ADDri); 5392da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 5393da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5394da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach case ARM::t2SUBri12: 5395da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub" 5396da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // mnemonic was used (not "subw"), encoding T3 is preferred. 5397da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" || 5398da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 5399da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5400da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.setOpcode(ARM::t2SUBri); 5401da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 5402da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 540389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 54040f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 54050f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 54060f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 54070f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 540883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 540989e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 541083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 541183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 541289e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 5413f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 5414f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 5415f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 5416f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 5417f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 541883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 5419f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 542083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 542183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 5422f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 5423927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach case ARM::t2ADDrr: { 5424927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // If the destination and first source operand are the same, and 5425927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // there's no setting of the flags, use encoding T2 instead of T3. 5426927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // Note that this is only for ADD, not SUB. This mirrors the system 5427927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // 'as' behaviour. Make sure the wide encoding wasn't explicit. 5428927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() || 5429927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach Inst.getOperand(5).getReg() != 0 || 5430713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 5431713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == ".w")) 5432927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach break; 5433927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach MCInst TmpInst; 5434927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.setOpcode(ARM::tADDhirr); 5435927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 5436927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 5437927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 5438927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5439927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 5440927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach Inst = TmpInst; 5441927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach return true; 5442927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach } 544351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 544451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 544583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) { 544651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 544783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 544883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 544951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 545051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 545151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 545283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){ 545351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 545483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 545583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 545651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 5457c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 5458a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 545983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) { 5460c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 546183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 546283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 5463c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 5464395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 5465395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 546683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) { 5467395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 546883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 546983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 54703ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 547176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 547276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 547376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 547476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 547576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 547676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 547776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 547876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 547976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 548076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 548176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 548276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 548376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 548476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 548576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 548676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 548776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 548876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 548976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 549076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 549176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 549283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 549376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 549476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 549576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 54968213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 54978213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 54988213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 54998213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 55008213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 55018213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 55028213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 55038213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 55048213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 55058213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 550683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55078213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 55088213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 55098213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 55105402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach case ARM::tPOP: { 55115402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach bool listContainsBase; 55125402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // If the register list contains any high registers, we need to use 55135402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 55145402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // should have generated an error in validateInstruction(). 55155402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase)) 551683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 55175402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach assert (isThumbTwo()); 55185402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.setOpcode(ARM::t2LDMIA_UPD); 55195402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Add the base register and writeback operands. 55205402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 55215402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 552283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55235402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach } 55245402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach case ARM::tPUSH: { 55255402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach bool listContainsBase; 55265402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase)) 552783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 55285402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach assert (isThumbTwo()); 55295402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.setOpcode(ARM::t2STMDB_UPD); 55305402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Add the base register and writeback operands. 55315402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 55325402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 553383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55345402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach } 55351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 55361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 55371ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 55381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 55391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 5540c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 5541c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 5542c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 55431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 55441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 55451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 55461ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 55471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 55481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 55491ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 55501ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 55511ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 55521ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 55531ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 555483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 55561ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 55571ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 55581ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 55591ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 55601ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 55611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 55621ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 55631ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 55641ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 55651ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 55661ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 55671ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 55681ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 55691ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 55701ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 55711ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 55721ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 55731ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 55741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 557583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55761ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 55771ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 55781ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 5579326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 558050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 558150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 558250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 5583326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 5584326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 5585326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 5586326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 5587326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 5588326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 5589326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 559050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 559150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 559250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 559350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 559450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 559550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 559650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 559750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 5598326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 5599326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 5600326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 5601326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 5602326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 5603326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5604326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 5605326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 560683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 5607326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 5608326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 5609326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 561089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 561189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 561289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 561389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 561489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 561589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 561689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 561789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 561889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 5619f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 5620f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 562189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 562289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 562389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 562489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 562589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 562689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 562789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 5628f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 5629f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 5630f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 5631f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 5632f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 5633f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 5634f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 5635f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 563689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 563789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 5638f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 563983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 5640f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 5641f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 564247a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 564347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 564447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 5645194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 56461a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCInstrDesc &MCID = getInstDesc(Opc); 564747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 564847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 564947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 565047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 565147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 565247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 565347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 565447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 565547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 565647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 565747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 565847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 565947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 566047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 566147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 566247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 5663f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 5664f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 566547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 5666f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 5667f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 5668f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 566947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 5670194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 5671194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 5672194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 5673194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 5674194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 5675194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 5676194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 56774ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 5678194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 5679194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 5680194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 568147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 568247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 568347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 5684fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 5685fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 5686fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 5687fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 5688fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 5689fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 569019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 5691193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 5692193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 569319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 5694e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 5695189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 5696189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 5697a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 5698a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 5699a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 5700a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 5701189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 5702a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 5703189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 5704f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 570583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // encoding is selected. Loop on it while changes happen so the 570683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // individual transformations can chain off each other. E.g., 570783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8) 570883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach while (processInstruction(Inst, Operands)) 570983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach ; 5710f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 5711a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 5712a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 5713a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 5714a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 5715a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 5716fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 5717fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 5718e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 5719e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 5720e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 5721e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 5722e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 5723e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 5724e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 5725e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 572616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5727e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 5728e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 5729e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 573016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5731e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 5732e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 5733e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 573447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 5735b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 573688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 573788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 5738f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 5739f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 574047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 574147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 5742194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 5743194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 5744194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 5745194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 5746fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 574716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5748c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 5749146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 5750fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 5751fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 57521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 5753ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 5754ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 5755ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 57561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 5757515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 57581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 57599a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach else if (IDVal == ".arm") 57609a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return parseDirectiveARM(DirectiveID.getLoc()); 5761515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 57621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 5763515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 57641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 5765515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 57661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 5767ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 5768ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 5769ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 57701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 5771ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 57721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 5773ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 5774ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 5775ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 5776ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 5777ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 5778ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5779aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 5780ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5781ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 5782ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 578316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5784ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 5785ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 5786ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 5787b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5788ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 5789ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 5790ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5791b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5792ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 5793ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 5794ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 57951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 5796515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 57971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 5798515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 5799515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 5800b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5801515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58029a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (!isThumb()) 58039a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach SwitchMode(); 58049a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 58059a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return false; 58069a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach} 58079a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach 58089a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM 58099a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// ::= .arm 58109a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) { 58119a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) 58129a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return Error(L, "unexpected token in directive"); 58139a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach Parser.Lex(); 58149a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach 58159a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (isThumb()) 58169a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach SwitchMode(); 58179a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 5818515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5819515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5820515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 5822515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 58231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 58246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 58256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 58266469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 58276469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 58286469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 58296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 58306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 58316469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 58326469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 58336469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 5834d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach Name = Tok.getIdentifier(); 58356469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 58366469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 58376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 5838d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) 5839515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 5840b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5841515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 58436469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 5844d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach Name = Parser.getTok().getIdentifier(); 58456469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 58466469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 5847642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 5848642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 5849642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 5850515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5851515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5852515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 5854515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 58551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 585618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5857515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 5858515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 585938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 586058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 5861b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 586258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 58639e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 5864515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 5865515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 5866515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5867515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 586818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 5869b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5870515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5871515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 5872515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 5873515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5874515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5875515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 5877515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 58781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 587918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5880515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 5881515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 588218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 588358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 5884b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 588558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 5886b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5887515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 5888515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 5889515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5890515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 589118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 5892b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5893515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 589432869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 589598447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 5896ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 589798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 589832869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 589998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 5900ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 590198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 5902eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 59032a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 5904515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5905515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5906515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 590790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 590890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 59099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 5910ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 591194b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 591294b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 591390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 5914ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 59153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 59160692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 59170692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 59183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 5919