ARMAsmParser.cpp revision 8d9550bde95c8d128e7bf62e9e65dec1854e2d1d
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 48a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach // Map of register aliases registers via the .req directive. 49a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach StringMap<unsigned> RegisterReqs; 50a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach 51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach struct { 52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes Cond; // Condition for IT block. 53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Mask:4; // Condition mask for instructions. 54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Starting at first 1 (from lsb). 55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '1' condition as indicated in IT. 56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '0' inverse of condition (else). 57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Count of instructions in IT block is 58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // 4 - trailingzeroes(mask) 59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool FirstCond; // Explicit flag for when we're parsing the 61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // First instruction in the IT block. It's 62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // implied in the mask, so needs special 63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // handling. 64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned CurPosition; // Current position in parsing of IT 66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // block. In range [0,3]. Initialized 67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // according to count of instructions in block. 68f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // ~0U if no active IT block. 69f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } ITState; 70f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool inITBlock() { return ITState.CurPosition != ~0U;} 71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach void forwardITPosition() { 72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (!inITBlock()) return; 73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Move to the next instruction in the IT block, if there is one. If not, 74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // mark the block as done. 75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach unsigned TZ = CountTrailingZeros_32(ITState.Mask); 76a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (++ITState.CurPosition == 5 - TZ) 77a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach ITState.CurPosition = ~0U; // Done with the IT block after this. 78a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 79f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 80f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 84ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 85ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 86ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 890d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 989a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach bool parseDirectiveARM(SMLoc L); 991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 1011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 102a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach bool parseDirectiveReq(StringRef Name, SMLoc L); 103a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach bool parseDirectiveUnreq(SMLoc L); 104d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim bool parseDirectiveArch(SMLoc L); 105d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim bool parseDirectiveEabiAttr(SMLoc L); 106515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 1071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 10889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool &CarrySetting, unsigned &ProcessorIMod, 10989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask); 1101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 111fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 11216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 113ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 114ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 115ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 116ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 117ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 118ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 119ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 12047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 12147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 12247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 123194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 124194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 125194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 126acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool hasV7Ops() const { 127acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::HasV7Ops; 128acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 12932869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 130ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 131ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 13232869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 133acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool isMClass() const { 134acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::FeatureMClass; 135acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 136ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1400692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1410692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 14589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 14643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 147f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 14843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 149f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 1509b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OperandMatchResultTy parseCoprocOptionOperand( 1519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 15243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1538bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 15443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1558bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 15643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1578bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 158f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 159f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 160f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 161f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 162f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 163f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 164f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 166c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 167580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 169293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 171251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 1729d39036f62674606565217a10db28171b9594bc7Jim Grosbach OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 173862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&); 1747636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index); 175ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 176ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 177a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 178a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 179a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 180a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 181eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 182eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 183ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 184ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 186ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1879ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 1889ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &); 189548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 190548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 192ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1937b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 2007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 2042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 20614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 207623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 208623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 21088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 21112431329d617064d6e72dd040a58c1635cc261abJim Grosbach bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, 21212431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 21312431329d617064d6e72dd040a58c1635cc261abJim Grosbach bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, 21412431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2154334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, 2164334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2174334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, 2184334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 219189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 220189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 221189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 22283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach bool processInstruction(MCInst &Inst, 223f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 224d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 225d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 226189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 227ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 22847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 229194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 230f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Match_RequiresNotITBlock, 231194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 232194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 23347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 23447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 235ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 23694b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 237ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 23832869205052430f45d598fba25ab878d8b29da2dEvan Cheng 239ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 240ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 241f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 242f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Not in an ITBlock to start with. 243f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = ~0U; 244ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 245ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 2471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 2481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 249189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 2501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 2511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 25247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 25347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 2541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 2551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 257ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 25816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 25916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2603a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 2613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 262a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 263a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 264146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CondCode, 26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CCOut, 26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ITCondMask, 26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocNum, 27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocReg, 2719b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach k_CoprocOption, 27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Immediate, 27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_FPImmediate, 27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MemBarrierOpt, 27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Memory, 27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_PostIndexRegister, 27721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MSRMask, 27821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ProcIFlags, 279460a90540b045c102012da2492999557e6840526Jim Grosbach k_VectorIndex, 28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Register, 28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RegisterList, 28221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_DPRRegisterList, 28321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_SPRRegisterList, 284862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach k_VectorList, 28598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach k_VectorListAllLanes, 2867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach k_VectorListIndexed, 28721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedRegister, 28821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedImmediate, 28921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShifterImmediate, 29021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RotateImmediate, 29121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_BitfieldDescriptor, 29221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Token 293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 294a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 29624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 299a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 3008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 3018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 3028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 3038462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 304fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 305fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 306fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 307fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 3089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach unsigned Val; 3099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } CoprocOption; 3109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 3119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach struct { 31289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 31389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 31489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 31589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 31689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 31789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 31889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 31989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 336862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // A vector register list is a sequential list of 1 to 4 registers. 337862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach struct { 338862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned RegNum; 339862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count; 3407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned LaneIndex; 3410aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach bool isDoubleSpaced; 342862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } VectorList; 343862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 3448155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 345460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned Val; 346460a90540b045c102012da2492999557e6840526Jim Grosbach } VectorIndex; 347460a90540b045c102012da2492999557e6840526Jim Grosbach 348460a90540b045c102012da2492999557e6840526Jim Grosbach struct { 349cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 350cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 35116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3529d39036f62674606565217a10db28171b9594bc7Jim Grosbach struct { 3539d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned Val; // encoded 8-bit representation 3549d39036f62674606565217a10db28171b9594bc7Jim Grosbach } FPImm; 3559d39036f62674606565217a10db28171b9594bc7Jim Grosbach 3566a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 357a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 358a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 3597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 3607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 3617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 3627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 3637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 36457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned ShiftImm; // shift for OffsetReg. 36557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment; // 0 = no alignment specified 366eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach // n = alignment in bytes (2, 4, 8, 16, or 32) 3677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 368e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach } Memory; 3690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 3700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 3717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 372f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 373f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 374f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 3757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 3767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 378580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 379e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 380580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 381e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 383e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 385e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 386af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 38792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 38892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 38992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 39092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 391af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 3927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 3937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 395293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 396293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 397293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 398293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 399a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 40016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 401146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 402146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 403762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 404762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 405762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 406762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 407762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 40821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 4098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 4108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 41121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: 41289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 41389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 4158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 416762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 41821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 419762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 420762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 42121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 42221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 42321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: 42424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 4258d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 426862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 42798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case k_VectorListAllLanes: 4287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case k_VectorListIndexed: 429862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach VectorList = o.VectorList; 430862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 43121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 43221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 433fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 434fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 4359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 4369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach CoprocOption = o.CoprocOption; 4379b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 43821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 439762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 440762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 44121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 4429d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImm = o.FPImm; 4439d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 44421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 445706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 446706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 44721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 448e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory = o.Memory; 449762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 45021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 4517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 4527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 45321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 454584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 455584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 45621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: 457a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 4580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 45921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 460580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 4610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 46221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 463af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 464e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 46521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 466af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 46792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 46821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 4697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 4707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 47121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 472293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 473293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 474460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 475460a90540b045c102012da2492999557e6840526Jim Grosbach VectorIndex = o.VectorIndex; 476460a90540b045c102012da2492999557e6840526Jim Grosbach break; 477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 47916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 480762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 481762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 482762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 483762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4858462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 48621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_CondCode && "Invalid access!"); 4878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 4888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 490fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 49121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 492fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 493fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 494fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 49621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Token && "Invalid access!"); 497a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 498a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 499a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 500a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 50121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 5027729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 503a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 504a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5055fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 50621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 50721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind == k_SPRRegisterList) && "Invalid access!"); 50824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 5098d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 5108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 511cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 51221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Immediate && "Invalid access!"); 513cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 514cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 515cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 5169d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned getFPImm() const { 51721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_FPImmediate && "Invalid access!"); 5189d39036f62674606565217a10db28171b9594bc7Jim Grosbach return FPImm.Val; 5199d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 5209d39036f62674606565217a10db28171b9594bc7Jim Grosbach 521460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned getVectorIndex() const { 522460a90540b045c102012da2492999557e6840526Jim Grosbach assert(Kind == k_VectorIndex && "Invalid access!"); 523460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val; 524460a90540b045c102012da2492999557e6840526Jim Grosbach } 525460a90540b045c102012da2492999557e6840526Jim Grosbach 526706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 52721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MemBarrierOpt && "Invalid access!"); 528706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 529706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 530706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 53221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_ProcIFlags && "Invalid access!"); 533a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 534a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 535a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 536584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 53721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MSRMask && "Invalid access!"); 538584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 539584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 540584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 54121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocNum() const { return Kind == k_CoprocNum; } 54221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocReg() const { return Kind == k_CoprocReg; } 5439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach bool isCoprocOption() const { return Kind == k_CoprocOption; } 54421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCondCode() const { return Kind == k_CondCode; } 54521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCCOut() const { return Kind == k_CCOut; } 54621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITMask() const { return Kind == k_ITCondMask; } 54721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITCondCode() const { return Kind == k_CondCode; } 54821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isImm() const { return Kind == k_Immediate; } 54921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isFPImm() const { return Kind == k_FPImmediate; } 550a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isImm8s4() const { 55121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 552a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 553a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 554a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!CE) return false; 555a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Value = CE->getValue(); 556a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 557a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 55872f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() 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 <= 1020; 56572f39f8436848885176943b0ba985a7171145423Jim Grosbach } 56672f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 56721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 56872f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 56972f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 57072f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 57172f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 57272f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 57372f39f8436848885176943b0ba985a7171145423Jim Grosbach } 5746b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 57521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5766b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5776b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 5816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 582587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach bool isImm0_1() 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 < 2; 589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach } 590587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach bool isImm0_3() const { 591587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (Kind != k_Immediate) 592587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return false; 593587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 594587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (!CE) return false; 595587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach int64_t Value = CE->getValue(); 596587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return Value >= 0 && Value < 4; 597587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach } 59883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() 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 < 8; 60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 60683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 60721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 60883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 60983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 61083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 61183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 61283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 61383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 6147c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 61521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6167c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 6177c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6187c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 6197c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 6207c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 6217c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 622730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach bool isImm0_63() const { 623730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach if (Kind != k_Immediate) 624730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach return false; 625730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 626730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach if (!CE) return false; 627730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach int64_t Value = CE->getValue(); 628730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach return Value >= 0 && Value < 64; 629730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach } 6303b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm8() 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 == 8; 6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm16() 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 == 16; 6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6463b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm32() const { 6473b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6483b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6493b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6503b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6513b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6523b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value == 32; 6533b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm8() 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 <= 8; 6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm16() 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 <= 16; 6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6706b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm32() 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 <= 32; 6776b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6786b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm64() const { 6796b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6806b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6816b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6826b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6836b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6846b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 64; 6856b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_7() 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 < 8; 6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_15() 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 < 16; 7013b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 7023b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_31() const { 7033b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 7043b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 7053b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7063b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 7073b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 7083b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value > 0 && Value < 32; 7093b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 710f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 71121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 712f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 713f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 714f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 715f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 716f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 717f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 7184a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 71921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 7204a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 7214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7224a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 7234a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 7244a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 7254a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 726ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach bool isImm0_32() const { 727ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (Kind != k_Immediate) 728ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach return false; 729ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 730ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (!CE) return false; 731ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach int64_t Value = CE->getValue(); 732ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach return Value >= 0 && Value < 33; 733ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach } 734fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 73521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 736fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 737fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 738fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 739fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 740fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 741fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 742ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 74321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 744ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 745ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 746ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 747ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 748ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 749ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 750ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 751ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 752ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 75321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 754ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 755ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 756ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 757ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 758ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 759ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 76070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 76121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 76270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 76370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 76470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 76570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 76670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 76770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 768f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() 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 } 776f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 77721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 778f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 779f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 780f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 781f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 782f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 783f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 7846bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 78521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 7866bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 7876bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7886bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 7896bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 7906bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 7916bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 792e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach bool isARMSOImmNot() const { 793e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach if (Kind != k_Immediate) 794e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach return false; 795e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 796e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach if (!CE) return false; 797e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach int64_t Value = CE->getValue(); 798e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach return ARM_AM::getSOImmVal(~Value) != -1; 799e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach } 8003bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach bool isARMSOImmNeg() const { 8013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (Kind != k_Immediate) 8023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return false; 8033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8043bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (!CE) return false; 8053bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach int64_t Value = CE->getValue(); 8063bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return ARM_AM::getSOImmVal(-Value) != -1; 8073bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 8086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 80921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 8106b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 8116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8126b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 8136b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 8146b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 8156b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 81689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach bool isT2SOImmNot() const { 81789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach if (Kind != k_Immediate) 81889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach return false; 81989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 82089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach if (!CE) return false; 82189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach int64_t Value = CE->getValue(); 82289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach return ARM_AM::getT2SOImmVal(~Value) != -1; 82389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach } 8243bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach bool isT2SOImmNeg() const { 8253bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (Kind != k_Immediate) 8263bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return false; 8273bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8283bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (!CE) return false; 8293bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach int64_t Value = CE->getValue(); 8303bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return ARM_AM::getT2SOImmVal(-Value) != -1; 8313bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 832c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 83321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 834c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 835c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 836c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 837c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 838c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 839c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 84021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isReg() const { return Kind == k_Register; } 84121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegList() const { return Kind == k_RegisterList; } 84221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 84321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 84421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isToken() const { return Kind == k_Token; } 84521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 84621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemory() const { return Kind == k_Memory; } 84721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isShifterImm() const { return Kind == k_ShifterImmediate; } 84821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 84921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 85021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRotImm() const { return Kind == k_RotateImmediate; } 85121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 85221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 853f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 854430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift; 855f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 85657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isMemNoOffset(bool alignOK = false) const { 857f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 858ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 8597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 86057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 && 86157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach (alignOK || Memory.Alignment == 0); 86257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 86357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isAlignedMemory() const { 86457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return isMemNoOffset(true); 865ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 8667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 86757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 8687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 869e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 8707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 871e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 872e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 8747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 875039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 87621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 877039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 878039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 879039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 880039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 881039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 882039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 883039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 8842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 8852f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 8862f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 8872f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // and we reject it. 8882f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 8892f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach return true; 89057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 8912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 892e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::no_shift) return false; 8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 894e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 8952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 896e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 897e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 8992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 90121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate && Kind != k_PostIndexRegister) 9022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 90321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) 9042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 9052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 9062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 9082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 909251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 910251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 9112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 913681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // If we have an immediate that's not a constant, treat it as a label 914681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // reference needing a fixup. If it is a constant, it's something else 915681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // and we reject it. 916681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 917681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach return true; 91857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 9197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 920e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return false; 9217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 922e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 923e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 9240da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 925681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Val == INT32_MIN; 9267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 9277f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBB() const { 928e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 92957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 9307f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 9317f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 9327f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 9337f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBH() const { 934e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 93557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 93657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0 ) 9377f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 9387f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 9397f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 9407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 94157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0) 942ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 943ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 944ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 945ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach bool isT2MemRegOffset() const { 94657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 94757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0) 948ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 949ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach // Only lsl #{0, 1, 2, 3} allowed. 950e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType == ARM_AM::no_shift) 951ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 952e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 953ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 954ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 955ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 9567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 9577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 9587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 959e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 96057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 96187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 962e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach return isARMLowRegister(Memory.BaseRegNum) && 963e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 96460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 96560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 966e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 96757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 96860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 96960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 970e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 971e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 972ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 973ecd858968384be029574d845eb098d357049e02eJim Grosbach } 97438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 975e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 97657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 97738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 97838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 979e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 980e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 98138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 98238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 98348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 984e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 98557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 98648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 98748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 988e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 989e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 99048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 99148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 992ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 99357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 99457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 995ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 996ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 997e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 998e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 999ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 1000505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1001a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isMemImm8s4Offset() const { 10022f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 10032f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 10042f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // and we reject it. 10052f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 10062f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach return true; 100757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1008a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 1009a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate offset a multiple of 4 in range [-1020, 1020]. 1010e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1011e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1012a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 1013a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1014b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach bool isMemImm0_1020s4Offset() const { 101557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1016b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return false; 1017b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // Immediate offset a multiple of 4 in range [0, 1020]. 1018e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1019e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1020b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 1021b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 10227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 102357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1024f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 10257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 1026e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1027e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 10284d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson return (Val == INT32_MIN) || (Val > -256 && Val < 256); 1029f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1030f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach bool isMemPosImm8Offset() const { 103157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1032f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return false; 1033f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach // Immediate offset in range [0, 255]. 1034e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1035e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1036f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return Val >= 0 && Val < 256; 1037f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1038a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemNegImm8Offset() const { 103957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1040a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 1041a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [-255, -1]. 1042df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach if (!Memory.OffsetImm) return false; 1043e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1044df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach return (Val == INT32_MIN) || (Val > -256 && Val < 0); 1045a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1046a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemUImm12Offset() const { 104757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1048a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 1049a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [0, 4095]. 1050e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1051e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1052a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return (Val >= 0 && Val < 4096); 1053a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 10547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 105509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 105609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 105709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 105821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 105909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 106009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 106157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1062ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 10637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 1064e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1065e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 10660da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 10677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 10687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 106921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 10707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 10717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1072ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 10737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 107463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 1075ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 10762bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isPostIdxImm8s4() const { 10772bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Kind != k_Immediate) 10782bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return false; 10792bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10802bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (!CE) return false; 10812bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int64_t Val = CE->getValue(); 10822bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 10832bd0118472de352745a2e038245fab4974f7c87eJim Grosbach (Val == INT32_MIN); 10842bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 10857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 108621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMSRMask() const { return Kind == k_MSRMask; } 108721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isProcIFlags() const { return Kind == k_ProcIFlags; } 10883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 10890e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // NEON operands. 10900aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach bool isSingleSpacedVectorList() const { 10910aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach return Kind == k_VectorList && !VectorList.isDoubleSpaced; 10920aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach } 10930aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach bool isDoubleSpacedVectorList() const { 10940aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach return Kind == k_VectorList && VectorList.isDoubleSpaced; 10950aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach } 1096862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach bool isVecListOneD() const { 10970aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (!isSingleSpacedVectorList()) return false; 1098862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return VectorList.Count == 1; 1099862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1100862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1101280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach bool isVecListTwoD() const { 11020aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (!isSingleSpacedVectorList()) return false; 1103280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach return VectorList.Count == 2; 1104280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach } 1105280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach 1106cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach bool isVecListThreeD() const { 11070aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (!isSingleSpacedVectorList()) return false; 1108cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach return VectorList.Count == 3; 1109cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach } 1110cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach 1111b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach bool isVecListFourD() const { 11120aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (!isSingleSpacedVectorList()) return false; 1113b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach return VectorList.Count == 4; 1114b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach } 1115b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach 11164661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach bool isVecListTwoQ() const { 11170aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (!isDoubleSpacedVectorList()) return false; 11180aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach return VectorList.Count == 2; 11194661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach } 11204661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach 11213471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach bool isSingleSpacedVectorAllLanes() const { 11223471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced; 11233471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach } 11243471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach bool isDoubleSpacedVectorAllLanes() const { 11253471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced; 11263471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach } 112798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach bool isVecListOneDAllLanes() const { 11283471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach if (!isSingleSpacedVectorAllLanes()) return false; 112998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return VectorList.Count == 1; 113098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 113198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 113213af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach bool isVecListTwoDAllLanes() const { 11333471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach if (!isSingleSpacedVectorAllLanes()) return false; 11343471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach return VectorList.Count == 2; 11353471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach } 11363471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach 11373471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach bool isVecListTwoQAllLanes() const { 11383471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach if (!isDoubleSpacedVectorAllLanes()) return false; 113913af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach return VectorList.Count == 2; 114013af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach } 114113af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach 114295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach bool isSingleSpacedVectorIndexed() const { 114395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced; 114495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach } 114595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach bool isDoubleSpacedVectorIndexed() const { 114695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced; 114795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach } 11487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach bool isVecListOneDByteIndexed() const { 114995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach if (!isSingleSpacedVectorIndexed()) return false; 11507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return VectorList.Count == 1 && VectorList.LaneIndex <= 7; 11517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 11527636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 1153799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach bool isVecListOneDHWordIndexed() const { 115495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach if (!isSingleSpacedVectorIndexed()) return false; 1155799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach return VectorList.Count == 1 && VectorList.LaneIndex <= 3; 1156799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach } 1157799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach 1158799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach bool isVecListOneDWordIndexed() const { 115995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach if (!isSingleSpacedVectorIndexed()) return false; 1160799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach return VectorList.Count == 1 && VectorList.LaneIndex <= 1; 1161799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach } 1162799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach 11639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach bool isVecListTwoDByteIndexed() const { 116495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach if (!isSingleSpacedVectorIndexed()) return false; 11659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return VectorList.Count == 2 && VectorList.LaneIndex <= 7; 11669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach } 11679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 1168799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach bool isVecListTwoDHWordIndexed() const { 116995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach if (!isSingleSpacedVectorIndexed()) return false; 117095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return VectorList.Count == 2 && VectorList.LaneIndex <= 3; 117195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach } 117295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach 117395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach bool isVecListTwoQWordIndexed() const { 117495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach if (!isDoubleSpacedVectorIndexed()) return false; 117595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return VectorList.Count == 2 && VectorList.LaneIndex <= 1; 117695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach } 117795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach 117895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach bool isVecListTwoQHWordIndexed() const { 117995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach if (!isDoubleSpacedVectorIndexed()) return false; 1180799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach return VectorList.Count == 2 && VectorList.LaneIndex <= 3; 1181799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach } 1182799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach 1183799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach bool isVecListTwoDWordIndexed() const { 118495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach if (!isSingleSpacedVectorIndexed()) return false; 1185799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach return VectorList.Count == 2 && VectorList.LaneIndex <= 1; 1186799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach } 1187799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach 1188460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex8() const { 1189460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1190460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 8; 1191460a90540b045c102012da2492999557e6840526Jim Grosbach } 1192460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex16() const { 1193460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1194460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 4; 1195460a90540b045c102012da2492999557e6840526Jim Grosbach } 1196460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex32() const { 1197460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1198460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 2; 1199460a90540b045c102012da2492999557e6840526Jim Grosbach } 1200460a90540b045c102012da2492999557e6840526Jim Grosbach 12010e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach bool isNEONi8splat() const { 12020e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (Kind != k_Immediate) 12030e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return false; 12040e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 12050e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Must be a constant. 12060e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!CE) return false; 12070e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach int64_t Value = CE->getValue(); 12080e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // i8 value splatted across 8 bytes. The immediate is just the 8 byte 12090e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // value. 12100e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return Value >= 0 && Value < 256; 12110e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 1212460a90540b045c102012da2492999557e6840526Jim Grosbach 1213ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach bool isNEONi16splat() const { 1214ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Kind != k_Immediate) 1215ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return false; 1216ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1217ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // Must be a constant. 1218ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (!CE) return false; 1219ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach int64_t Value = CE->getValue(); 1220ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // i16 value in the range [0,255] or [0x0100, 0xff00] 1221ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00); 1222ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1223ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 12246248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32splat() const { 12256248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 12266248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 12276248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 12286248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 12296248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 12306248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 12316248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X. 12326248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 12336248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 12346248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 12356248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000); 12366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 12376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 12386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32vmov() const { 12396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 12406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 12416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 12426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 12436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 12446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 12456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 12466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 12476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 12486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 12496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 12506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000) || 12516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 12526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 12536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 12549b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach bool isNEONi32vmovNeg() const { 12559b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach if (Kind != k_Immediate) 12569b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach return false; 12579b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 12589b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach // Must be a constant. 12599b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach if (!CE) return false; 12609b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach int64_t Value = ~CE->getValue(); 12619b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 12629b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 12639b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach return (Value >= 0 && Value < 256) || 12649b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 12659b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 12669b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000) || 12679b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 12689b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 12699b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach } 12706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1271f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach bool isNEONi64splat() const { 1272f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (Kind != k_Immediate) 1273f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return false; 1274f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1275f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // Must be a constant. 1276f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (!CE) return false; 1277f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1278f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // i64 value with each byte being either 0 or 0xff. 1279f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i) 1280f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 1281f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return true; 1282f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1283f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 12843483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 128514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 128614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 128714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 128814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 12893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 12903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 12913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 12923483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 12933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1295345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 12968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 129704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 129804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 12998462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 13008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1301fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 1302fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1303fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 1304fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1305fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 13069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 13079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 13089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(getCoproc())); 13099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 13109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 13119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 13129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 13139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val)); 13149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 13159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 131689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 131789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 131889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 131989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 132089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 132189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 132289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 132389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 132489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 132589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 1326d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 1327d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1328d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 1329d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1330d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 1331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 1332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 1333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 1334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1336af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 1337e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1338430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach assert(isRegShiftedReg() && 1339430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach "addRegShiftedRegOperands() on non RegShiftedReg!"); 1340af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 1341af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 1342e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 1343af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 1344e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1345e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1346af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 1347152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 1348430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach assert(isRegShiftedImm() && 1349430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach "addRegShiftedImmOperands() on non RegShiftedImm!"); 1350af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 135192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 1352af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 135392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 135492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1355580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 13560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 1357580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 1358580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 13590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 13600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 136187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 13627729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 13635fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 13645fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 13657729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 13667729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 136787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 136887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 13690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 13700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 13710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 13720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 13730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 13740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 13750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 13760f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 13777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 13787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 13807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 13817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 13827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1383293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1384293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1385293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 1386293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 1387293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 1388293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1389293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1390293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 1391293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 1392293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1393293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 13943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 13956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 13976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 13986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 13999d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 14009d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 14019d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 14029d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 14039d39036f62674606565217a10db28171b9594bc7Jim Grosbach 1404a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1405a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1406a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 1407a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 1408a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1409a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1410a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1411a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 141272f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 141372f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 141472f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 141572f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 141672f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 141772f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 141872f39f8436848885176943b0ba985a7171145423Jim Grosbach } 141972f39f8436848885176943b0ba985a7171145423Jim Grosbach 142072f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 142172f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 142272f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 142372f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 142472f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 142572f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 142672f39f8436848885176943b0ba985a7171145423Jim Grosbach } 142772f39f8436848885176943b0ba985a7171145423Jim Grosbach 1428f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1429f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1430f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1431f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1432f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1433f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1434f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1435f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 14364a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 14374a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 14384a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 14394a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 14404a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14414a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 14424a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 14434a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 144470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 144570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 144670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 144770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 144870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 144970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 145070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1451ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1452ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1453f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1454f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1455f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1456f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1457f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1458f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1459f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1460f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1461f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 146289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const { 146389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 146489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach // The operand is actually a t2_so_imm, but we have its bitwise 146589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach // negation in the assembly source, so twiddle it here. 146689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 146789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 146889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach } 146989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach 14703bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const { 14713bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 14723bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // The operand is actually a t2_so_imm, but we have its 14733bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // negation in the assembly source, so twiddle it here. 14743bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14753bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 14763bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 14773bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach 1478e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const { 1479e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1480e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach // The operand is actually a so_imm, but we have its bitwise 1481e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach // negation in the assembly source, so twiddle it here. 1482e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1483e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 1484e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach } 1485e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach 14863bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const { 14873bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 14883bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // The operand is actually a so_imm, but we have its 14893bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // negation in the assembly source, so twiddle it here. 14903bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14913bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 14923bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 14933bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach 1494706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1495706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1496706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1497706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1498706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 14997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 15007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1501e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1502505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1503505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 150457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 150557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 150657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 150757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 150857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 150957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 15107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 15117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1512e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1513e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 15147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 15157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 15167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 15177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 15187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 15197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 15207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 15217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 1522e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1523e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1524ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1525e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1526e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 15277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1528ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1529ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1530039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1531039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1532039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1533039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1534039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1535039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1536039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1537039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1538039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1539039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1540039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1541039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1542039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1543039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 15442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 15452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 15462f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 15472f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 15482f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // and we reject it. 15492f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if (isImm()) { 15502f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach Inst.addOperand(MCOperand::CreateExpr(getImm())); 15512f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 15522f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 15532f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach return; 15542f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach } 15552f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 1556e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1557e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 15582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 15592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 15602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 15612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 15622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 15632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 15642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 15652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 1566e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 15672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 1568e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1569e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 15702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 15712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 15722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 15732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 15742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 157521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) { 15762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 15772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 15782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 15792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1580251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 15812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 15822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 15832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 15842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 15852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 15862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 15872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 15882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 15892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1590251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 15912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 15922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 15932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 15942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 15957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 15967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1597681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // If we have an immediate that's not a constant, treat it as a label 1598681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // reference needing a fixup. If it is a constant, it's something else 1599681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // and we reject it. 1600681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach if (isImm()) { 1601681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Inst.addOperand(MCOperand::CreateExpr(getImm())); 1602681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1603681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach return; 1604681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach } 1605681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach 16067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1607e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 16087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 16097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 16107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 16117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 16127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 1613e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 16147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 16157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 16167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1617a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1618a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 16192f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 16202f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 16212f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // and we reject it. 16222f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if (isImm()) { 16232f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach Inst.addOperand(MCOperand::CreateExpr(getImm())); 16242f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 16252f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach return; 16262f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach } 16272f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach 1628e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1629e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1630a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1631a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1632a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1633b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1634b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1635b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1636e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1637e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1638b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1639b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1640b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 16417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 16427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1643e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1644e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 16457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1646ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1647ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1648f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1649f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1650f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1651f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1652a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1653f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1654a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1655a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1656a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1657a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1658a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 165921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 1660a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1661a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1662a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1663a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1664a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1665a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1666e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1667e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1668a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1669a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1670a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 16717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 16727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 167309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 167421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 167509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 167609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 167709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 167809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 167909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 168009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1681e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1682e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 16837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 16847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 168592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 16867f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 16877f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1688e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1689e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 16907f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 16917f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 16927f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 16937f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1694e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1695e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 16967f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 16977f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 16987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 16997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1700430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach unsigned Val = 1701430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1702430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach Memory.ShiftImm, Memory.ShiftType); 1703e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1704e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 17057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 17067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1707d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1708ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1709ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1710e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1711e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1712e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 1713ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1714ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 17157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 17167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1717e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1718e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 171914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 17203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 172160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 172260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1723e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1724e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 172560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 172648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 172748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 172838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 172938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1730e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 1731e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 173238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 173338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 173438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 173548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 173648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1737e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 1738e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 173948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 174060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 174160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1742ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1743ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1744e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1745e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1746ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1747ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1748ecd858968384be029574d845eb098d357049e02eJim Grosbach 17497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 17507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 17517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 17527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 17537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 17547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 175563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 17567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 17577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1758f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1759ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 17602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 17612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 17622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 17632bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(CE && "non-constant post-idx-imm8s4 operand!"); 17642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int Imm = CE->getValue(); 17652bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isAdd = Imm >= 0; 17662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Imm == INT32_MIN) Imm = 0; 17672bd0118472de352745a2e038245fab4974f7c87eJim Grosbach // Immediate is scaled by 4. 17682bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 17692bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 17702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 17712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach 17727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 17737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 17747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1775f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1776f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1777f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1778f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1779f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1780f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1781f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1782f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1783f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1784f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1785f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1786f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1787ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1788ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1789584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1790584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1791584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1792584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1793584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1794a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1795a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1796a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1797a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1798a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 17996029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach void addVecListOperands(MCInst &Inst, unsigned N) const { 1800862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1801862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1802862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1803862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 18047636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach void addVecListIndexedOperands(MCInst &Inst, unsigned N) const { 18057636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 18067636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 18077636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex)); 18087636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 18097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 1810460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1811460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1812460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1813460a90540b045c102012da2492999557e6840526Jim Grosbach } 1814460a90540b045c102012da2492999557e6840526Jim Grosbach 1815460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1816460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1817460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1818460a90540b045c102012da2492999557e6840526Jim Grosbach } 1819460a90540b045c102012da2492999557e6840526Jim Grosbach 1820460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1821460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1822460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1823460a90540b045c102012da2492999557e6840526Jim Grosbach } 1824460a90540b045c102012da2492999557e6840526Jim Grosbach 18250e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 18260e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 18270e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // The immediate encodes the type of constant as well as the value. 18280e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Mask in that this is an i8 splat. 18290e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 18300e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00)); 18310e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 18320e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 1833ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 1834ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1835ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // The immediate encodes the type of constant as well as the value. 1836ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1837ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach unsigned Value = CE->getValue(); 1838ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Value >= 256) 1839ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value = (Value >> 8) | 0xa00; 1840ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach else 1841ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value |= 0x800; 1842ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 1843ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1844ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 18456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 18466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 18476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 18486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 18496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 18506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xff00) 18516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | 0x200; 18526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xff0000) 18536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | 0x400; 18546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 18556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 18566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 18576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 18586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 18596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 18606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 18616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 18626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 18636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 18646248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xffff) 18656248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 18666248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xffffff) 18676248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 18686248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 18696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 18709b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 18719b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach } 18729b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach 18739b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const { 18749b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 18759b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach // The immediate encodes the type of constant as well as the value. 18769b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 18779b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach unsigned Value = ~CE->getValue(); 18789b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach if (Value >= 256 && Value <= 0xffff) 18799b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 18809b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach else if (Value > 0xffff && Value <= 0xffffff) 18819b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 18829b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach else if (Value > 0xffffff) 18839b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach Value = (Value >> 24) | 0x600; 18846248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 18856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 18866248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1887f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 1888f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1889f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // The immediate encodes the type of constant as well as the value. 1890f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1891f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1892f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach unsigned Imm = 0; 1893f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 1894f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Imm |= (Value & 1) << i; 1895f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1896f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00)); 1897f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1898f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 1899b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1900b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 190189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 190221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ITCondMask); 190389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 190489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 190589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 190689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 190789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 190889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 19093a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 191021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CondCode); 1911345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1912345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1913345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 19143a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1915345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1916345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1917fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 191821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocNum); 1919fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1920fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1921fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1922fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1923fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1924fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1925fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 192621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocReg); 1927fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1928fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1929fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1930fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1931fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1932fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 19339b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) { 19349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocOption); 19359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->Cop.Val = Val; 19369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->StartLoc = S; 19379b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->EndLoc = E; 19389b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return Op; 19399b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 19409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 1941d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 194221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CCOut); 1943d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1944d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1945d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1946d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1947d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1948d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 19493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 195021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Token); 1951762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1952762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1953762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1954762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 19553a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1956a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1957a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 195850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 195921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Register); 1960762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1961762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1962762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 19633a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1964a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1965a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1966e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1967e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1968e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1969e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1970e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 197121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1972af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1973af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1974af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1975af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1976e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1977e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1978e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1979e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1980e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 198192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 198292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 198392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 198492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 198521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1986af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1987af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1988af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 198992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 199092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 199192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 199292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 199392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1994580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 19950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 199621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1997580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1998580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 19990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 20000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 20010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 20020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 20030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 20047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 200521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_RotateImmediate); 20067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 20077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 20087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 20097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 20107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2012293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 2013293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 201421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 2015293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 2016293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 2017293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 2018293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 2019293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 2020293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2021293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 20227729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 20235fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 2024cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 202521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach KindTy Kind = k_RegisterList; 20260f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 2027d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 202821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_DPRRegisterList; 2029d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 2030275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 203121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_SPRRegisterList; 20320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 20330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 20345fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 20357729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 203624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 2037cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 2038cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 2039cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 20408d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 20418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 20428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 2043862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count, 20440aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach bool isDoubleSpaced, SMLoc S, SMLoc E) { 2045862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorList); 2046862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.RegNum = RegNum; 2047862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.Count = Count; 20480aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Op->VectorList.isDoubleSpaced = isDoubleSpaced; 2049862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->StartLoc = S; 2050862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->EndLoc = E; 2051862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return Op; 2052862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2053862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 205498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count, 20553471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach bool isDoubleSpaced, 205698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc S, SMLoc E) { 205798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorListAllLanes); 205898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->VectorList.RegNum = RegNum; 205998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->VectorList.Count = Count; 20603471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach Op->VectorList.isDoubleSpaced = isDoubleSpaced; 206198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->StartLoc = S; 206298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->EndLoc = E; 206398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Op; 206498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 206598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 20667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count, 206795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach unsigned Index, 206895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach bool isDoubleSpaced, 206995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach SMLoc S, SMLoc E) { 20707636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorListIndexed); 20717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.RegNum = RegNum; 20727636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.Count = Count; 20737636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.LaneIndex = Index; 207495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Op->VectorList.isDoubleSpaced = isDoubleSpaced; 20757636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->StartLoc = S; 20767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->EndLoc = E; 20777636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return Op; 20787636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 20797636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 2080460a90540b045c102012da2492999557e6840526Jim Grosbach static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 2081460a90540b045c102012da2492999557e6840526Jim Grosbach MCContext &Ctx) { 2082460a90540b045c102012da2492999557e6840526Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorIndex); 2083460a90540b045c102012da2492999557e6840526Jim Grosbach Op->VectorIndex.Val = Idx; 2084460a90540b045c102012da2492999557e6840526Jim Grosbach Op->StartLoc = S; 2085460a90540b045c102012da2492999557e6840526Jim Grosbach Op->EndLoc = E; 2086460a90540b045c102012da2492999557e6840526Jim Grosbach return Op; 2087460a90540b045c102012da2492999557e6840526Jim Grosbach } 2088460a90540b045c102012da2492999557e6840526Jim Grosbach 20893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 209021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Immediate); 2091762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 2092762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 2093762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 20943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 2095cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 2096cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 20979d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 209821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_FPImmediate); 20999d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 21009d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 21019d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 21029d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 21039d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 21049d39036f62674606565217a10db28171b9594bc7Jim Grosbach 21057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 21067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 21077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 21087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 21090d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 211057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment, 21117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 21123a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 211321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Memory); 2114e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.BaseRegNum = BaseRegNum; 2115e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetImm = OffsetImm; 2116e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetRegNum = OffsetRegNum; 2117e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftType = ShiftType; 2118e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftImm = ShiftImm; 211957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Op->Memory.Alignment = Alignment; 2120e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.isNegative = isNegative; 21217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 21227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 21237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 21247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 212516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2126f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 2127f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 2128f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 21297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 213021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 21317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 2132f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 2133f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 2134f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 2135762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 2136762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 21373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 2138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2139706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2140706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 214121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 2142706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 2143706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 2144706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 2145706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 2146706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 2147a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2148a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 214921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ProcIFlags); 2150a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 2151a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 2152a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 2153a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 2154a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2155584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2156584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 215721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MSRMask); 2158584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 2159584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 2160584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 2161584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 2162584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2163a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 2164a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2165a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 2166a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2167b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 2168fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 216921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 21709d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 21719d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 21729d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 217321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 21746a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 2175fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 217621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 2177d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 2178d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 217921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: { 21801a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer static const char *MaskStr[] = { 21811a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)", 21821a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)" 21831a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer }; 218489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 218589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 218689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 218789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 218821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 2189fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 2190fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 219121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 2192fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 2193fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 21949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 21959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OS << "<coprocessor option: " << CoprocOption.Val << ">"; 21969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 219721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 2198584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 2199584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 220021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 2201fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 2202fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 220321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 2204706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 2205706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 220621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 22076ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 2208e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach << " base:" << Memory.BaseRegNum; 22096ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 2210fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 221121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 2212f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 2213f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 2214f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 2215f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 2216f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 2217f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 22187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 221921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: { 2220a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 2221a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 2222a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 2223a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 2224a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 2225a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 2226a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 2227a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 222821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 222950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 2230fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 223121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 2232580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 2233580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 2234e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 223521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 223692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 2237efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << RegShiftedReg.SrcReg << " " 2238efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) 2239efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << " " << RegShiftedReg.ShiftReg << ">"; 22400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 224121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 224292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 2243efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << RegShiftedImm.SrcReg << " " 2244efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) 2245efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << " #" << RegShiftedImm.ShiftImm << ">"; 224692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 224721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 22487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 22497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 225021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 2251293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 2252293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 2253293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 225421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 225521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 225621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: { 22578d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 22588d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 22595fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 22605fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 22617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 22627729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 22637729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 22648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 22658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 22668d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 22678d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 22688d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 2269862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 2270862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OS << "<vector_list " << VectorList.Count << " * " 2271862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach << VectorList.RegNum << ">"; 2272862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 227398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case k_VectorListAllLanes: 227498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach OS << "<vector_list(all lanes) " << VectorList.Count << " * " 227598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach << VectorList.RegNum << ">"; 227698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 22777636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case k_VectorListIndexed: 22787636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OS << "<vector_list(lane " << VectorList.LaneIndex << ") " 22797636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach << VectorList.Count << " * " << VectorList.RegNum << ">"; 22807636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 228121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 2282fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 2283fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 2284460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 2285460a90540b045c102012da2492999557e6840526Jim Grosbach OS << "<vectorindex " << getVectorIndex() << ">"; 2286460a90540b045c102012da2492999557e6840526Jim Grosbach break; 2287fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 2288fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 22893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 22903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 22913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 22923483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 22933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 22943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 22953483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 22963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 229769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 229869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 2299a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach StartLoc = Parser.getTok().getLoc(); 23001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 2301a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach EndLoc = Parser.getTok().getLoc(); 2302bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 2303bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 2304bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 2305bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 23069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 2307e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 2308e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 23093a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 23101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 231118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 23127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 2313d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 2314590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string lowerCase = Tok.getString().lower(); 23150c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 23160c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 23170c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 23180c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 23190c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 23200c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 23210c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 232240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach // Additional register name aliases for 'gas' compatibility. 232340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a1", ARM::R0) 232440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a2", ARM::R1) 232540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a3", ARM::R2) 232640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a4", ARM::R3) 232740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v1", ARM::R4) 232840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v2", ARM::R5) 232940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v3", ARM::R6) 233040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v4", ARM::R7) 233140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v5", ARM::R8) 233240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v6", ARM::R9) 233340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v7", ARM::R10) 233440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v8", ARM::R11) 233540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("sb", ARM::R9) 233640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("sl", ARM::R10) 233740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("fp", ARM::R11) 23380c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 23390c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 2340a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach if (!RegNum) { 2341aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach // Check for aliases registered via .req. Canonicalize to lower case. 2342aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach // That's more consistent since register names are case insensitive, and 2343aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach // it's how the original entry was passed in from MC/MCParser/AsmParser. 2344aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase); 2345a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach // If no match, return failure. 2346a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach if (Entry == RegisterReqs.end()) 2347a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return -1; 2348a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach Parser.Lex(); // Eat identifier token. 2349a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return Entry->getValue(); 2350a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach } 235169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 2352b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 2353460a90540b045c102012da2492999557e6840526Jim Grosbach 2354e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 2355e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 2356d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 235719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 235819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 235919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 236019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 236119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 23620d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 23630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 23650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 23660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 23670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2368590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string lowerCase = Tok.getString().lower(); 23690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 2370af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach .Case("asl", ARM_AM::lsl) 23710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 23720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 23730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 23740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 23750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 23760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 23770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 23780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 237919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 23800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2381e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 2382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 2383e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 2384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 2385e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 2386eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 2387e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 2388e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 2389e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 2390e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 2391e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 2392e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 2393e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 2394e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 2395e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 2396e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 2397e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 2398e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 23998a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 24008a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar)) { 2401e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 2402e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 2403e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 240419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 240519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 240619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 240719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2408e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 2409e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 241019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 241119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 241219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 241319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2414e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 2415e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 2416e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 2417e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 2418e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 2419e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 2420e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 242119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 242219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 2423e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2424de626ad8726677328e10dbdc15011254214437d7Jim Grosbach // shift by zero is a nop. Always send it through as lsl. 2425de626ad8726677328e10dbdc15011254214437d7Jim Grosbach // ('as' compatibility) 2426de626ad8726677328e10dbdc15011254214437d7Jim Grosbach if (Imm == 0) 2427de626ad8726677328e10dbdc15011254214437d7Jim Grosbach ShiftTy = ARM_AM::lsl; 2428e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 24291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 2430e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 243119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 243219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 243319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 243419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 243519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 243619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 2437e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 243819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 243919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2440e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2441e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 244292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 244392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 2444af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 24450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 244692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 244792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 244892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 24490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 245019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 24510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 24520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 24530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 245450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 245550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 245650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 2457e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 2458e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 2459e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 246050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 24611355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2462e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 24631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 2464e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 246550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2466d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 246750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 2468a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2469e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 2470e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 247150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 247250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 2473e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 2474460a90540b045c102012da2492999557e6840526Jim Grosbach return false; 2475460a90540b045c102012da2492999557e6840526Jim Grosbach } 2476460a90540b045c102012da2492999557e6840526Jim Grosbach 2477460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 2478460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 2479460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 2480460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 2481460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 2482460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 2483460a90540b045c102012da2492999557e6840526Jim Grosbach 2484460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 2485460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 2486460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2487460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2488460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 2489460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 2490460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2491460a90540b045c102012da2492999557e6840526Jim Grosbach } 2492460a90540b045c102012da2492999557e6840526Jim Grosbach 2493460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2494460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 2495460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 2496460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2497460a90540b045c102012da2492999557e6840526Jim Grosbach } 2498460a90540b045c102012da2492999557e6840526Jim Grosbach 2499460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 2500460a90540b045c102012da2492999557e6840526Jim Grosbach 2501460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 2502460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 2503460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 250499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 250599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 250650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2508a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2509fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 2510fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 2511fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 2512fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 2513e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 2514e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 2515e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 2516e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 2517e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 2518fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 2519e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2520e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 2521e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2522e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 2523e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 2524e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 2525e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 2526e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 2527e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 2528e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 2529e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 2530e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 2531e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 2532e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2533e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2534e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 2535fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 2536e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2537e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 2538e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2539e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 2540e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 2541e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 2542e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 2543e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 2544e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 2545e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2546e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2547e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2548e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2549e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2550e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2551e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 255289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 255389df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 255489df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 255589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 255689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 255789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 255889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 255989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 256089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 256189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 256289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 256389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 256489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 256589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 256689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 256789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 256889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 256989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 257089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 257189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 257289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 257389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 257489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 257589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 257689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 257789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 257889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 257989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 258089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 258189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 258289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 258389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 258489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 258589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 258689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 258743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2588fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2589fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2590f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 259143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2592e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 2593e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 2594c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2595c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2596e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2597fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2598e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 2599f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2600e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2601e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 2602fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2603f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2604fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 2605fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 260643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2607fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2608fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2609f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 261043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2611fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2612fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2613c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2614c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2615fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2616fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2617fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 2618f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2619fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2620fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2621fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2622f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2623e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2624e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 26259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 26269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}' 26279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 26289b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 26299b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc S = Parser.getTok().getLoc(); 26309b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 26319b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // If this isn't a '{', this isn't a coprocessor immediate operand. 26329b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 26339b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_NoMatch; 26349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '{' 26359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 26369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCExpr *Expr; 26379b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 26389b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (getParser().ParseExpression(Expr)) { 26399b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "illegal expression"); 26409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 26419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 26429b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 26439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 26449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 26459b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 26469b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 26479b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach int Val = CE->getValue(); 26489b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 26499b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // Check for and consume the closing '}' 26509b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 26519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 26529b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc E = Parser.getTok().getLoc(); 26539b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '}' 26549b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 26559b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 26569b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_Success; 26579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach} 26589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 2659d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 2660d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 2661d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 2662d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 2663d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 2664d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 2665d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 2666d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2667d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 2668d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 2669d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 2670d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2671d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2672d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2673d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2674d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2675d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2676d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2677d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2678d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2679d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 2680d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2681ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register. 2682ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) { 2683ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach switch (QReg) { 2684ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach default: llvm_unreachable("expected a Q register!"); 2685ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q0: return ARM::D0; 2686ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q1: return ARM::D2; 2687ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q2: return ARM::D4; 2688ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q3: return ARM::D6; 2689ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q4: return ARM::D8; 2690ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q5: return ARM::D10; 2691ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q6: return ARM::D12; 2692ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q7: return ARM::D14; 2693ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q8: return ARM::D16; 269425e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach case ARM::Q9: return ARM::D18; 2695ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q10: return ARM::D20; 2696ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q11: return ARM::D22; 2697ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q12: return ARM::D24; 2698ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q13: return ARM::D26; 2699ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q14: return ARM::D28; 2700ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q15: return ARM::D30; 2701ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 2702ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach} 2703ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach 2704d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 270550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 27061355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 270718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 2708a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 2709e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 2710d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 2711d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 271216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2713d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 2714d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 2715d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 2716d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 2717d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 2718d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2719ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 2720ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // space for that many. 2721ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2722ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach 2723ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2724ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2725ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Reg = getDRegFromQReg(Reg); 2726ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2727ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach ++Reg; 2728ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 27291a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCRegisterClass *RC; 2730d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2731d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2732d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2733d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2734d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2735d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2736d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 2737d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2738e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 2739ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Store the register. 2740d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2741d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2742d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 2743d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 2744d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 2745d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2746d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2747d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2748e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.Lex(); // Eat the minus. 2749d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2750d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 2751d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2752d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2753ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2754ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 2755ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach EndReg = getDRegFromQReg(EndReg) + 1; 2756d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2757d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2758d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2759d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2760d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2761d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2762d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2763d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2764d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2765d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2766d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2767d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2768d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2769d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2770d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2771d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2772d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2773d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2774d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2775d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2776d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2777a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach const AsmToken RegTok = Parser.getTok(); 2778d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2779d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 27802d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2781ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2782ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach bool isQReg = false; 2783ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2784ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Reg = getDRegFromQReg(Reg); 2785ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach isQReg = true; 2786ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 2787d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2788d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2789d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2790d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2791a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg)) 2792d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2793a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) { 2794a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach Warning(RegLoc, "duplicated register (" + RegTok.getString() + 2795a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach ") in register list"); 2796a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach continue; 2797a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach } 2798d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2799d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2800d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2801d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2802d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2803d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2804d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2805ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (isQReg) 2806ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc)); 2807d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2808d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2809d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2810d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2811d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2812d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2813e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 281427debd60a152d39e421c57bce511f16d8439a670Jim Grosbach // Push the register list operand. 281550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 281627debd60a152d39e421c57bce511f16d8439a670Jim Grosbach 281727debd60a152d39e421c57bce511f16d8439a670Jim Grosbach // The ARM system instruction variants for LDM/STM have a '^' token here. 281827debd60a152d39e421c57bce511f16d8439a670Jim Grosbach if (Parser.getTok().is(AsmToken::Caret)) { 281927debd60a152d39e421c57bce511f16d8439a670Jim Grosbach Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc())); 282027debd60a152d39e421c57bce511f16d8439a670Jim Grosbach Parser.Lex(); // Eat '^' token. 282127debd60a152d39e421c57bce511f16d8439a670Jim Grosbach } 282227debd60a152d39e421c57bce511f16d8439a670Jim Grosbach 282350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2824d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2825d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 282698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists. 282798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 28287636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) { 28297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Index = 0; // Always return a defined index value. 283098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 283198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Parser.Lex(); // Eat the '['. 283298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Parser.getTok().is(AsmToken::RBrac)) { 283398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // "Dn[]" is the 'all lanes' syntax. 283498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach LaneKind = AllLanes; 283598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Parser.Lex(); // Eat the ']'. 283698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_Success; 283798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 2838c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach const MCExpr *LaneIndex; 2839c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 2840c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach if (getParser().ParseExpression(LaneIndex)) { 2841c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach Error(Loc, "illegal expression"); 2842c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach return MatchOperand_ParseFail; 28437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 2844c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex); 2845c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach if (!CE) { 2846c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach Error(Loc, "lane index must be empty or an integer"); 2847c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach return MatchOperand_ParseFail; 2848c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach } 2849c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 2850c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach Error(Parser.getTok().getLoc(), "']' expected"); 2851c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach return MatchOperand_ParseFail; 2852c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach } 2853c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach Parser.Lex(); // Eat the ']'. 2854c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach int64_t Val = CE->getValue(); 2855c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach 2856c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach // FIXME: Make this range check context sensitive for .8, .16, .32. 2857c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach if (Val < 0 || Val > 7) { 2858c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach Error(Parser.getTok().getLoc(), "lane index out of range"); 2859c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach return MatchOperand_ParseFail; 2860c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach } 2861c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach Index = Val; 2862c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach LaneKind = IndexedLane; 2863c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach return MatchOperand_Success; 286498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 286598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach LaneKind = NoLanes; 286698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_Success; 286798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach} 286898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 2869862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list 2870862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2871862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 287298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy LaneKind; 28737636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned LaneIndex; 28745c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach SMLoc S = Parser.getTok().getLoc(); 28755c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // As an extension (to match gas), support a plain D register or Q register 28765c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // (without encosing curly braces) as a single or double entry list, 28775c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // respectively. 28785c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) { 28795c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach int Reg = tryParseRegister(); 28805c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Reg == -1) 28815c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_NoMatch; 28825c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 28835c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) { 28847636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex); 288598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Res != MatchOperand_Success) 288698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Res; 288798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 288898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 288998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind!"); 289098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 289198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 28920aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E)); 289398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 289498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 289598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 28963471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false, 28973471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach S, E)); 289898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 28997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 29007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1, 290195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach LaneIndex, 290295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach false, S, E)); 29037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 290498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 29055c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_Success; 29065c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 29075c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 29085c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Reg = getDRegFromQReg(Reg); 29097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex); 291098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Res != MatchOperand_Success) 291198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Res; 291298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 291398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 291498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind!"); 291598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 291698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 29170aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E)); 291898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 291998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 292098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 29213471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false, 29223471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach S, E)); 292398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 29247636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 29257636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2, 292695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach LaneIndex, 292795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach false, S, E)); 29287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 292998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 29305c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_Success; 29315c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 29325c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Error(S, "vector register expected"); 29335c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_ParseFail; 29345c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 29355c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach 29365c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 2937862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_NoMatch; 2938862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2939862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '{' token. 2940862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 2941862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2942862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int Reg = tryParseRegister(); 2943862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2944862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2945862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2946862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2947862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count = 1; 2948276ed0344c05822617934fa4a6a9920d864193a5Jim Grosbach int Spacing = 0; 2949c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach unsigned FirstReg = Reg; 2950c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // The list is of D registers, but we also allow Q regs and just interpret 2951c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // them as the two D sub-registers. 2952c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2953c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach FirstReg = Reg = getDRegFromQReg(Reg); 29540aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Spacing = 1; // double-spacing requires explicit D registers, otherwise 29550aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach // it's ambiguous with four-register single spaced. 2956c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Reg; 2957c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Count; 2958c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 29597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success) 296098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 2961c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach 2962e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2963e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2964e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 29650aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (!Spacing) 29660aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Spacing = 1; // Register range implies a single spaced list. 29670aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach else if (Spacing == 2) { 29680aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Error(Parser.getTok().getLoc(), 29690aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach "sequential registers in double spaced list"); 29700aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach return MatchOperand_ParseFail; 29710aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach } 2972e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.Lex(); // Eat the minus. 2973e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2974e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach int EndReg = tryParseRegister(); 2975e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (EndReg == -1) { 2976e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "register expected"); 2977e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2978e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 2979e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2980e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 2981e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach EndReg = getDRegFromQReg(EndReg) + 1; 2982e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // If the register is the same as the start reg, there's nothing 2983e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // more to do. 2984e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Reg == EndReg) 2985e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach continue; 2986e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // The register must be in the same register class as the first. 2987e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) { 2988e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "invalid register in register list"); 2989e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2990e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 2991e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Ranges must go from low to high. 2992e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Reg > EndReg) { 2993e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "bad range in register list"); 2994e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2995e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 299698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 299798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 29987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 29997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 300098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 30017636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 300298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 300398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 300498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 300598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach EndLoc = Parser.getTok().getLoc(); 3006e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach 3007e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Add all the registers in the range to the register list. 3008e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Count += EndReg - Reg; 3009e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Reg = EndReg; 3010e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach continue; 3011e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 3012862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat the comma. 3013862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach RegLoc = Parser.getTok().getLoc(); 3014862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int OldReg = Reg; 3015862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Reg = tryParseRegister(); 3016862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 3017862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 3018862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 3019862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 3020c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // vector register lists must be contiguous. 3021862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // It's OK to use the enumeration values directly here rather, as the 3022862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // VFP register classes have the enum sorted properly. 3023c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // 3024c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // The list is of D registers, but we also allow Q regs and just interpret 3025c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // them as the two D sub-registers. 3026c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 30270aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (!Spacing) 30280aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Spacing = 1; // Register range implies a single spaced list. 30290aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach else if (Spacing == 2) { 30300aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Error(RegLoc, 30310aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach "invalid register in double-spaced list (must be 'D' register')"); 30320aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach return MatchOperand_ParseFail; 30330aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach } 3034c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Reg = getDRegFromQReg(Reg); 3035c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (Reg != OldReg + 1) { 3036c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Error(RegLoc, "non-contiguous register range"); 3037c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach return MatchOperand_ParseFail; 3038c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 3039c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Reg; 3040c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Count += 2; 304198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 304298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 30437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 304498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 30457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 304698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 30477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 304898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 304998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 305098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 3051c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach continue; 3052c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 30530aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach // Normal D register. 30540aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach // Figure out the register spacing (single or double) of the list if 30550aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach // we don't know it already. 30560aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (!Spacing) 30570aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Spacing = 1 + (Reg == OldReg + 2); 30580aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach 30590aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach // Just check that it's contiguous and keep going. 30600aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach if (Reg != OldReg + Spacing) { 3061862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "non-contiguous register range"); 3062862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 3063862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 3064862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ++Count; 306598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 306698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 30677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 306898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 30697636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 307098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 30717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 307298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 307398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 307498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 3075862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 3076862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 3077862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 3078862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) { 3079862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(E, "'}' expected"); 3080862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 3081862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 3082862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '}' token. 3083862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 308498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 308598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 308698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind in register list."); 308798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 30880aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, 30890aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach (Spacing == 2), S, E)); 309098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 309198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 309298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count, 30933471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach (Spacing == 2), 309498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach S, E)); 309598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 30967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 30977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count, 309895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach LaneIndex, 309995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach (Spacing == 2), 310095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach S, E)); 31017636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 310298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 3103862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_Success; 3104862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach} 3105862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 310643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 3107f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 310843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3109706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 3110706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 3111706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 3112706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 3113706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 3114706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 3115706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 3116706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 3117032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 3118706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 3119032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 3120706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 3121706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 3122032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 3123706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 3124032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 3125706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 3126706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 3127706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 3128706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 3129706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 3130f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 3131706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 3132706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 3133706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 3134f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 3135706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 3136706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 313743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 3138a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 313943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3140a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 3141a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 3142a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 3143a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 3144a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 31452dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // An iflags string of "none" is interpreted to mean that none of the AIF 31462dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // bits are set. Not a terribly useful instruction, but a valid encoding. 3147a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 31482dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (IFlagsStr != "none") { 31492dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 31502dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 31512dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("a", ARM_PROC::A) 31522dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("i", ARM_PROC::I) 31532dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("f", ARM_PROC::F) 31542dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Default(~0U); 31552dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 31562dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // If some specific iflag is already set, it means that some letter is 31572dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // present more than once, this is not acceptable. 31582dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (Flag == ~0U || (IFlags & Flag)) 31592dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson return MatchOperand_NoMatch; 31602dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 31612dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson IFlags |= Flag; 31622dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson } 3163a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3164a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3165a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 3166a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 3167a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 3168584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 3169584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 317043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 3171584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 317243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3173584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 3174584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 3175584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 3176584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 3177584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3178acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 3179acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 3180acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 3181acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 3182acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 3183acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 3184acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 3185acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 3186acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 3187acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 3188acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 3189acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 3190acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 3191acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 3192acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 3193acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 3194acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 3195acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 319618c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach 3197acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 3198acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 3199acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3200acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 3201acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 3202acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 320318c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach 3204acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 3205acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 3206acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 3207acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 3208acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3209584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 3210584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 3211584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 3212590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string SpecReg = Mask.slice(Start, Next).lower(); 3213584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 3214584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 3215584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3216584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 3217584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 3218584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 3219584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 3220584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3221584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 3222584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 3223b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 3224584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 3225584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 3226584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 3227584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 32284b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 3229584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 3230584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3231584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 3232bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 32334b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 3234584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 323556926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 323656926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 3237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 3238584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 3239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 3240584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 3241584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 3242584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 3243584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 3244584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3245584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 3246584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 3247584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 3248584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3249584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 3250584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 3251584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 3252584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3253584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 32547784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // Special register without flags is NOT equivalent to "fc" flags. 32557784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // NOTE: This is a divergence from gas' behavior. Uncommenting the following 32567784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // two lines would enable gas compatibility at the expense of breaking 32577784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // round-tripping. 32587784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // 32597784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // if (!FlagsVal) 32607784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // FlagsVal = 0x9; 3261584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3262584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 3263584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 3264584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 3265584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3266584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 3267584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 3268584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 3269a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 3270a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3271f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3272f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 3273f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 3274f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 3275f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3276f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 3277f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3278f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3279f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 3280590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string LowerOp = Op.lower(); 3281590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string UpperOp = Op.upper(); 3282f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 3283f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 3284f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3285f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3286f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 3287f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3288f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 32898a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 32908a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3291f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3292f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3293f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3294f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 3295f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3296f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 3297f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 3298f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 3299f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 3300f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3301f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3302f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 3303f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 3304f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 3305f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3306f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3307f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 3308f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 3309f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 3310f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3311f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3312f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3313f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 3314f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3315f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 3316f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 3317f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3318c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3319c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3320c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 3321c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 3322c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3323c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 3324c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 3325c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 3326c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 3327c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 3328c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 3329c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 3330c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 3331c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 3332c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 3333c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 3334c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 3335c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 3336c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 3337c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 3338c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 3339c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 3340c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 3341c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 3342580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 3343580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 3344580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 3345580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 3346580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 3347580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3348580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3349580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 3350580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 3351580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3352580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 3353580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3354580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3355580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 3356580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 3357580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 3358580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 3359580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 3360580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 3361580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 3362580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 3363580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3364580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3365580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 3366580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3367580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 33688a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 33698a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3370580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3371580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3372580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3373580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 3374580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3375580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 3376580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 3377580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 3378580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 3379580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3380580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3381580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 3382580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 3383580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 3384580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3385580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3386580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3387580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 3388580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 3389580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 3390580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 3391580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 3392580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3393580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 33940afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 33950afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 33960afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 33970afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 33980afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 3399580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 3400580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 3401580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 3402580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 3403580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 3404580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3405580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3406580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3407580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3408580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 3409580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 3410580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3411580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 3412580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 3413580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 34147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 34157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 34167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 34177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 34187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 34197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 34207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 3421326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 3422326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 34237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 3424326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 3425326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 34267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 34277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 34287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 34298a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 34308a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 34317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 34327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 34337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 34347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 34357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 34367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 34377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 34387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 34397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 34407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 34417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 34427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 34437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 34447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 34457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 34467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 34477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 34487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 34497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 34507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 34517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 34527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 34537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 34547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 34557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 34567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 34577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 34587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 34597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 34607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 34617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 34627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 3463293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3464293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3465293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 3466293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 34678a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 34688a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3469293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3470293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3471293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3472293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 3473293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3474293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 3475293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3476293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 3477293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 3478293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3479293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3480293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 3481293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 3482293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 3483293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3484293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3485293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3486293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 3487293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 3488293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 3489293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 3490293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3491293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3492293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 3493293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3494293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 3495293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 3496293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 3497293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3498293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3499293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 35008a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 35018a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3502293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3503293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3504293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3505293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 3506293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3507293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 3508293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 3509293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 3510293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3511293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3512293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 3513293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 3514293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 3515293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3516293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3517293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3518293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 3519293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 3520293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 3521293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 3522293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3523293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3524293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 3525293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3526293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 3527293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3528293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 3529293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 3530293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 35317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 35327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 35337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 3534f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 3535f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 3536f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 35377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 35387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 35397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 35407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 35417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 35427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 35437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 354416578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 35457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 35467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 35477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 35487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 35497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 35507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 355116578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 35527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 35537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 35547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 35557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 35567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 35577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 35587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 35597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 35607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 35617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 35627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 35637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3564f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 3565f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 35660d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 35670d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 35680d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 35690d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 35700d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 3571f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 3572f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 3573f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 35747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 35757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 35767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 35777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3578251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3579251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3580251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 3581251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 3582251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 3583251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 3584251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 3585251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 3586251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 3587251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3588251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 3589251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 3590251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 3591251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 3592251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 3593251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3594251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 35958a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 35968a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar)) { 3597251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 3598251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 3599251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 3600251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 3601251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 3602251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 3603251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3604251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 3605251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 3606251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 3607251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3608251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3609251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 3610251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 3611251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 3612251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 3613251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 3614251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3615251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 3616251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 3617251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3618251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3619251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3620251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3621251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3622251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 3623251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 3624251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 3625251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 3626251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 3627251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 3628251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 3629251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 3630251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 3631251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 3632251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3633251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 3634251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 3635251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 3636251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 3637251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 3638251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 3639251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3640251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3641251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3642251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3643251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 3644251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 3645251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3646251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3647251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 3648251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3649a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 3650a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3651a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3652a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3653a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 3654a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3655a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3656a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3657a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3658a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3659a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3660a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3661a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3662a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3663a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3664a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3665a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3666a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3667a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 3668a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3669a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3670a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3671a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 3672a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3673a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3674a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3675a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3676a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3677a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3678a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3679a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3680a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3681a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3682a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3683a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3684a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3685eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3686eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3687eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3688eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 3689eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3690eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3691eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3692eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3693eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 3694eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3695eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3696eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3697eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3698eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 3699eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 3700eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3701ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3702ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3703ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3704ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 3705ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3706ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3707ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 3708ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3709ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3710ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3711ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3712ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 3713ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 3714ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 37151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3716ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3717ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3718ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 37191355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3720ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3721ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3722ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 3723ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3724ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3725ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 37267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3727ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3728ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3729ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3730ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 37319ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 37329ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 37339ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 37349ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 37359ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 37369ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 37379ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 37389ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 37399ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 37409ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 37419ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 37429ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 37439ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 37449ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 37459ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 37469ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 37479ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 3748548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 3749548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3750548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3751548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 3752548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 3753548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3754548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 3755548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3756548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3757548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 3758548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3759548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 3760548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 3761548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 37621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3763ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3764ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3765ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 37661355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3767ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3768ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3769ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3770548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3771548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3772548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 37737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 37747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 37757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 37767b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 37777b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 37787b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 37797b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 37807b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 37817b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 37827b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 37837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 37847b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 37857b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 37867b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 37877b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 37887b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 37897b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 37907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 37917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 37927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 37937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 37947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 37957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 37967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3797ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 37987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 37997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 38007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 38017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 38027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 38037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 38047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3805ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3806ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3807ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3808ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 38097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 3810ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3811ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3812ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 38137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 38147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 38157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3816aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3817ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3818ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 38197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 38207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 38217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 38227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 38237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 38247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 38257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 38267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 3827aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 38287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 38297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 38307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 38317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 38327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 38337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 38347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 38357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 38367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 38377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 38387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 38397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 38407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 38417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 38427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3843ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3844ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3845ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3846ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 38477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 3848ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3849ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3850ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 38517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 38527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3853ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3854ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 38557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3856ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 38577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 38587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 38597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 38607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 38617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3862ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3863ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3864ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3865ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 38662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 38672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 38682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 38692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 38702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 38712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 38722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 38732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 38742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 38752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 38762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 38772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 38782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 38792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 38802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 38812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 38822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 38832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 388414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 388514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 388614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 388714605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 388814605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 388914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 389014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 389114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 389214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 389314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 389414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 389514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 389614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 389714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 389814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 389914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 390014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 390114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 3902623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 3903623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3904623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3905623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 3906623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 3907623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3908623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3909623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 3910623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3911623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 3912623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3913623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 3914623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 3915623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 391688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 391788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 391888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 391988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 392088ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 392188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 392288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 392388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 392488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 39257a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 39267a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 39277a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 39287a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 392988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 39307a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 393188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 393288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 393388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 393488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 39351b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach // If we have a three-operand form, make sure to set Rn to be the operand 39361b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach // that isn't the same as Rd. 39371b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach unsigned RegOp = 4; 39381b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach if (Operands.size() == 6 && 39391b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[4])->getReg() == 39401b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[3])->getReg()) 39411b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach RegOp = 5; 39421b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1); 39431b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach Inst.addOperand(Inst.getOperand(0)); 394488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 394588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 394688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 394788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 3948623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 394912431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser:: 395012431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode, 395112431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 395212431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vd 39536029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 395412431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Create a writeback register dummy placeholder. 395512431329d617064d6e72dd040a58c1635cc261abJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 395612431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vn 395712431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 395812431329d617064d6e72dd040a58c1635cc261abJim Grosbach // pred 395912431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 396012431329d617064d6e72dd040a58c1635cc261abJim Grosbach return true; 396112431329d617064d6e72dd040a58c1635cc261abJim Grosbach} 396212431329d617064d6e72dd040a58c1635cc261abJim Grosbach 396312431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser:: 396412431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode, 396512431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 396612431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vd 39676029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 396812431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Create a writeback register dummy placeholder. 396912431329d617064d6e72dd040a58c1635cc261abJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 397012431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vn 397112431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 397212431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vm 397312431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 397412431329d617064d6e72dd040a58c1635cc261abJim Grosbach // pred 397512431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 397612431329d617064d6e72dd040a58c1635cc261abJim Grosbach return true; 397712431329d617064d6e72dd040a58c1635cc261abJim Grosbach} 397812431329d617064d6e72dd040a58c1635cc261abJim Grosbach 39794334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser:: 39804334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode, 39814334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 39824334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Create a writeback register dummy placeholder. 39834334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 39844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vn 39854334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 39864334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vt 39876029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 39884334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // pred 39894334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 39904334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach return true; 39914334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach} 39924334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach 39934334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser:: 39944334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode, 39954334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 39964334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Create a writeback register dummy placeholder. 39974334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 39984334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vn 39994334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 40004334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vm 40014334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 40024334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vt 40036029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 40044334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // pred 40054334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 40064334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach return true; 40074334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach} 40084334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach 4009e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 40109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 401150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 40127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4013762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 401418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 4015a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 4016762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 4017b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 4018a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 401918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 40201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 40217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 40227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 4023a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40240571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 40250571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 40260571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 40277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 40280571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 40297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 4030762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 4031b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 4032a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 403457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 0, 0, false, S, E)); 403503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 4036fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 4037fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 4038fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 4039fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 4040fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 4041fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 4042fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 40437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 40447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 404550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 40467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 40477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 404850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 404957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a ':', it's an alignment specifier. 405057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Colon)) { 405157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the ':'. 405257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 405357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 405457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCExpr *Expr; 405557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (getParser().ParseExpression(Expr)) 405657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return true; 405757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 405857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // The expression has to be a constant. Memory references with relocations 405957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // don't come through here, as they use the <label> forms of the relevant 406057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // instructions. 406157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 406257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!CE) 406357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error (E, "constant expression expected"); 406457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 406557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Align = 0; 406657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach switch (CE->getValue()) { 406757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach default: 4068eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach return Error(E, 4069eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach "alignment specifier must be 16, 32, 64, 128, or 256 bits"); 4070eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 16: Align = 2; break; 4071eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach case 32: Align = 4; break; 407257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 64: Align = 8; break; 407357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 128: Align = 16; break; 407457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 256: Align = 32; break; 407557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 407657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 407757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Now we should have the closing ']' 407857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 407957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 408057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "']' expected"); 408157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat right bracket token. 408257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 408357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Don't worry about range checking the value here. That's handled by 408457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // the is*() predicates. 408557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 408657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, Align, 408757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 408857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 408957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 409057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // operand. 409157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 409257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 409357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the '!'. 409457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 409557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 409657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return false; 409757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 409857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 409957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a '#', it's an immediate offset, else assume it's a register 41006cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach // offset. Be friendly and also accept a plain integer (without a leading 41016cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach // hash) for gas compatibility. 41026cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 41038a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar) || 41046cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach Parser.getTok().is(AsmToken::Integer)) { 41058a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Integer)) 41066cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach Parser.Lex(); // Eat the '#'. 41077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 410850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 41090da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 41107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 41117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 41127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 411305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 41147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 41157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 41167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 41177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 41187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 41197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 41207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 41210da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 41220da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 41230da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 41240da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 41250da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 41267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 41277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 41287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 41297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 41307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 413105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 41327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 41337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 41347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 413557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, 0, 413657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 4137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 41387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 41397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 41407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 41417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 41427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 4143762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 41447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 41457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 41469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 4147d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 41487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 41497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 41507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 41517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 41527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 41537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 41547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 41557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 41567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 41579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 41587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 41597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 41607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 41617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 41627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 41637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 41647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 41650d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 41667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 41677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 41680d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 41697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 41709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 417116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 41727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 41737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 41747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 41757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 41767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 41777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 41787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 417957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ShiftType, ShiftImm, 0, isNegative, 41807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 41817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 4182f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 4183f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 4184f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 4185f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 4186f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 4187f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 41889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 41899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 41909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 41919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 41927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 4193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 4194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 41957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 41967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 41977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 41987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 419918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 4201a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 420238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 4203af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL" || 4204af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach ShiftName == "asl" || ShiftName == "ASL") 42050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 4206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 42070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 4208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 42090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 4210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 42110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 4212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 42130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 4214a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 42157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 4216b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 4217a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 42187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 42197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 42207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 42217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 42227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 42237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 42248a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (HashTok.isNot(AsmToken::Hash) && 42258a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach HashTok.isNot(AsmToken::Dollar)) 42267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 42277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 42289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 42297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 42307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 42317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 42327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 42337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 42347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 42357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 42367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 42377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 42387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 42397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 42407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 42417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 42427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 42437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 42447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 4245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4246a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 4247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 4248a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 42499d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 42509d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 42519d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 42529d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 42539d39036f62674606565217a10db28171b9594bc7Jim Grosbach 42548a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 42558a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) 42569d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 42570e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 42580e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Disambiguate the VMOV forms that can accept an FP immediate. 42590e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <sreg>, #imm 42600e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f64 <dreg>, #imm 42610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <dreg>, #imm @ vector f32x2 42620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <qreg>, #imm @ vector f32x4 42630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // 42640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // There are also the NEON VMOV instructions which expect an 42650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // integer constant. Make sure we don't try to parse an FPImm 42660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // for these: 42670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.i{8|16|32|64} <dreg|qreg>, #imm 42680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]); 42690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!TyOp->isToken() || (TyOp->getToken() != ".f32" && 42700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach TyOp->getToken() != ".f64")) 42710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return MatchOperand_NoMatch; 42720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 42739d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 42749d39036f62674606565217a10db28171b9594bc7Jim Grosbach 42759d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 42769d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 42779d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 42789d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 42799d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 42809d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 42819d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 42829d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 42839d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 42849d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 42859d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 42869d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 42879d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 42889d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 42899d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 42909d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 42919d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 42929d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 42939d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 42949d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 42959d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 42969d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 42979d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 42989d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 42999d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 43009d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 43019d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 43029d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 43039d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 43049d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 43059d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 43069d39036f62674606565217a10db28171b9594bc7Jim Grosbach 43079d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 43089d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 43099d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 43109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 43119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 43121355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4313fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 4314762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 4315fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 4316fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 4317fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 4318f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 4319f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 4320fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 4321f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 4322f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 4323f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 4324f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 4325f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 4326fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 4327a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 4328146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 4329146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 433050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 433119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 43321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 433350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 43340d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 433519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 43360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 433719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 433819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 43393cbe43fe69680df772d83947ced97ca445861213Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 43405cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 43415cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 43425cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 43435cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 43445cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 43455cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 4346e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 4347e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 4348e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 434919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 4350758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach case AsmToken::LParen: // parenthesized expressions like (_strcmp-4) 435167b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 43526284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach case AsmToken::String: // quoted label names. 435367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 4354515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 4355515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 4356515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 4357762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 4358515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 435950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 4360762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 436150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 436250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 436350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 4364a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 43651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 4366d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 43671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 43688a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach case AsmToken::Dollar: 436963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 4370079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 4371079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 4372762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 4373b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 437463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 4375515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 4376515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 437750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 437863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 4379ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach if (CE) { 4380ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach int32_t Val = CE->getValue(); 4381ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach if (isNegative && Val == 0) 4382ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 438363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 4384762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 438550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 438650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 438763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 43889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 43899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 43907597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 43917597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 43927597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 43931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 43949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 43959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 43967597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 43977597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 43989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 43999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 44007597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 44017597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 44029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 44037597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 44049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 44059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 4406a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4407a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 4408a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 44091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 44107597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 44111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 44127597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 44139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 44149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 44158a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 44169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 44179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 44189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 44199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 44209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 44219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 44229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 44239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 44249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 44257597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 44269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 44277597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 44289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 44299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 44309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 44319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 44329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 44339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 44349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 44359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 44369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 44379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 44389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 44399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 44409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 44419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 4442352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 4443352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 4444352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 4445badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 444689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 44471355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 44485f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 44495f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 445089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 445189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 4452352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 4453352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 4454a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 4455352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 4456badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 4457352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 4458352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 44595f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 44605f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 44615f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 44625f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 44635f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 44645f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 44655f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 44666849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" || 44676849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach Mnemonic == "fmuls") 4468352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 4469badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 44703f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 44713f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 4472ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 447371725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 447404d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 44752f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 44763f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 44773f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 44783f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 44793f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 44803f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 44813f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 44823f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 44833f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 44843f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 44853f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 44863f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 44873f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 44883f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 44893f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 44903f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 44913f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 44923f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 44933f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 44943f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 44953f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 44963f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 44973f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 44983f00e317064560ad11168d22030416d853829f6eJim Grosbach } 449952925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 4500345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4501352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 4502352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 4503352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 450400f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 45055f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 45065f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 45075f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 450867ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" || 450948171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" || 45109c39789c361d4fe2632f28fca74c9ea5fff3dafcJim Grosbach Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" || 45116849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach Mnemonic == "fmuls" || 4512e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 4513352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 4514352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 4515352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 4516352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 4517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 4518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 4519a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 4520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 4521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 4522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 4523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 4524a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 4525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 4526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 4527a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 4528a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 4529a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4530a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 453289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 453389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 453489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 453589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 453689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 453789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4538352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 4539352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 45403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 45413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 45423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 45433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 45443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 4545fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 45461355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 4547fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 4548eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 4549eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 45503443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 4551eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 4552d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 4553eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 4554d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 45553443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 4556d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 4557d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 4558eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 4559fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 4560eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 45613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 4562eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 4563eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 4564eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 4565eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 4566ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 4567ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 45680780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 45692bd0118472de352745a2e038245fab4974f7c87eJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" || 45702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "ldc2" || Mnemonic == "ldc2l" || 45712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) || 45724af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 45734af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 45741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 45753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 4576fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 45773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 4578fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 4579fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 4580fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 458163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 4582fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 4583fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 4584badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 4585badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 4586d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 4587d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 458820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 458920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 4590d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 4591d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 4592d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 4593d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 4594d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 4595d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 4596d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 4597d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 4598d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 45998adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 4600d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 4601d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 4602d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 4603d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 46043912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 46053912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 46063912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 46073912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 46083912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 46093912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 46103912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 46113912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 461272f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 461320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 461420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 461520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 4616f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 4617f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 4618f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 461972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 462072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 462172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 462220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 462320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 462420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 462572f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 4626f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 4627f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 462820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 462920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 463020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 4631f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 4632f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 463320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 463420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 463520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 463620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 463720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 463820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 463920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 464020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 464120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 464220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 464320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 464420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 464520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 464620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 464720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 464864944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 464920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 465020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 465120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 465220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 465320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 465420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 465520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 465620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 465720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 465864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 465964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 466064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 466164944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 466264944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 466364944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 466464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 466564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 466664944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 466764944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 466864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 466964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 467064944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 467164944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 46721de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) || 467364944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 467464944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 467564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 467664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 467764944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 467864944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 467964944f48a1164c02c15ca423a53919682a89074cJim Grosbach 46807f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // Also check the 'mul' syntax variant that doesn't specify an explicit 46817f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // destination register. 46827f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 && 46837f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 46847f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 46857f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 46867f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // If the registers aren't low regs or the cc_out operand is zero 46877f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 46887f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // remove the cc_out operand. 46897f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 46907f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 46917f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach !inITBlock())) 46927f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach return true; 46937f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach 469464944f48a1164c02c15ca423a53919682a89074cJim Grosbach 469520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 4696f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 4697f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 4698f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 4699f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 4700f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 4701f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 4702f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 470372f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 470472f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 470572f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 470672f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 47073912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 4708d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 4709d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 4710d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 47117aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) { 47127aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" || 47137aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" || 47147aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" || 47157aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" || 47167aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" || 47177aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".f" || Tok == ".d"; 47187aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach} 47197aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 47207aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class 47217aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be 47227aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now. 47237aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) { 47247aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm"); 47257aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach} 47267aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 472721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features); 4728badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 4729badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 4730badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 473121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // Apply mnemonic aliases before doing anything else, as the destination 473221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // mnemnonic may include suffices and we want to handle them normally. 473321d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // The generic tblgen'erated code does this later, at the start of 473421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // MatchInstructionImpl(), but that's too late for aliases that include 473521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // any sort of suffix. 473621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach unsigned AvailableFeatures = getAvailableFeatures(); 473721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach applyMnemonicAliases(Name, AvailableFeatures); 473821d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach 4739a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach // First check for the ARM-specific .req directive. 4740a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier) && 4741a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach Parser.getTok().getIdentifier() == ".req") { 4742a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach parseDirectiveReq(Name, NameLoc); 4743a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach // We always return 'error' for this, as we're done with this 4744a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach // statement and don't need to match the 'instruction." 4745a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return true; 4746a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach } 4747a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach 4748badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 4749badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 4750ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 4751badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 4752352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 4753352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 4754a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 4755352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 475689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 47571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 475889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 4759badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 47600c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 47610c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 47620c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 47630c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 47640c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 47650c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 4766ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 4767ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 476889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 476989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 477089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 477189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 477289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 477389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 4774f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 4775f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 4776f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 4777f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 4778f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 477989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 478089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 478189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 478289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 478389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 4784f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 478589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 478689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 478789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 478889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 478989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4790f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 479189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 479289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4793ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 4794ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 47959717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 47963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 47973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 47983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 47993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 48003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 48013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 48023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 48033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 48041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 48053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 480633c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 480733c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 480833c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 480933c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 4810ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 481133c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 481233c16a27370939de39679245c3dff72383c210bdJim Grosbach } 4813c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 4814c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 4815c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 4816c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 4817c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 4818c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 4819c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 482033c16a27370939de39679245c3dff72383c210bdJim Grosbach 48213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 4822f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 4823f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 48243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 4825f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 4826f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 48273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 48283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 48293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 4830f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 4831f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 48323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 4833f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 4834badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 4835345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4836a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 4837a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 4838a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 4839a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 4840a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 4841a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4842a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 4843345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 48445747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 48455747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 48465747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 4847a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 4848a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 48497aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach // Some NEON instructions have an optional datatype suffix that is 48507aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach // completely ignored. Check for that. 48517aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach if (isDataTypeToken(ExtraToken) && 48527aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken)) 48537aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach continue; 48547aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 485581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 485681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 485781d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 485881d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 48595747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 48605747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 48615747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 48625747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 4863a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 48641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4865cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4866cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4867cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4868a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4869a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 4870b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 4871a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4872a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 48731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4874cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4875cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4876cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4877a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4878a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 487916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4880cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 4881186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach SMLoc Loc = getLexer().getLoc(); 4882cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4883186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach return Error(Loc, "unexpected token in argument list"); 4884cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4885146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 488634e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 4887ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4888d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 4889d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 4890d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 489120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 489220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 489320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 489420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 489520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 4896ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4897ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 4898ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 4899ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 4900ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4901cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 4902cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 4903cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 490421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // a k_CondCode operand in the list. If we're trying to match the label 490521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // version, remove the k_CondCode operand here. 4906cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 4907cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 4908cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4909cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 4910cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 4911cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 4912857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 4913857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 4914857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 4915857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 4916857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 4917857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 4918857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4919857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4920857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4921857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 4922857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 4923857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 492468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 492568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 492668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 492768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 492868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 492968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 493068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 493168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 493268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 493368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 493468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4935857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 4936857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4937857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4938934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 493955b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach // end. Convert it to a token here. Take care not to convert those 494055b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach // that should hit the Thumb2 encoding. 4941934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 494255b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 494355b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 4944934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4945934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4946934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 494755b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach if (CE && CE->getValue() == 0 && 494855b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach (isThumbOne() || 4949d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach // The cc_out operand matches the IT block. 4950d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach ((inITBlock() != CarrySetting) && 4951d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach // Neither register operand is a high register. 495255b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 4953d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){ 4954934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 4955934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4956934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 4957934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4958934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4959934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 49609898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 4961ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4962ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4963189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 4964aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 4965aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 4966aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 4967aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 4968aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 4969aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 4970aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 4971aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 4972aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 4973aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 4974aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 4975aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 4976aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 4977aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 4978aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 4979aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 4980aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 4981aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 498276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 498376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 498476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 498576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 498676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 498776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 498876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 498976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 499076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 499176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 499276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 4993f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 4994f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 4995f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 4996f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 49971a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[]; 4998f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 49991a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) { 5000f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 5001f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 5002f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 5003189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 5004189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 5005189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 5006189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 50071a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 5008f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 5009f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 5010b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 5011b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 5012b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 5013b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 5014f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 5015f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 5016f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 5017f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 5018a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 5019f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 5020f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 5021f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 5022f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 5023f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 5024f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 5025f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 5026f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 5027f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 5028f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 5029f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 5030f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 5031f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 5032f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 5033f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 5034f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 5035f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 5036c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 5037f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 5038f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 503951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 504051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 5041f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 5042f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 5043189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 50442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 50452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 50462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 5047189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 5048189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 5049189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 5050189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 5051189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 5052189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 5053189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 5054189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 5055189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 505614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 505714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 505814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 505914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 506014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 506114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 506214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 506314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 506414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 506553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 506653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 5067189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 5068189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 5069189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 5070189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 5071189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 507214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 5073189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 5074189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 5075189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 5076fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 5077fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 5078fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 5079fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 5080fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 5081fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 5082fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 5083fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 508400c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 5085fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 508693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 508776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 508876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 508976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 509076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 509176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 509293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 509393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 509493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 50957260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 50967260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 50977260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 5098aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 509976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 5100aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 5101aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 510293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 510376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 510493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 510593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 510676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 510776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 5108aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 51097260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 51107260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 51117260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 511293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 511393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 511493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 511576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 511676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 511776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 511876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 511976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 512076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 512176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 51225402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2, 51235402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // so only issue a diagnostic for thumb1. The instructions will be 51245402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // switched to the t2 encodings in processInstruction() if necessary. 51256dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 5126aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 51275402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) && 51285402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach !isThumbTwo()) 5129aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 5130aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 51316dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 51326dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 51336dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 5134aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 51355402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) && 51365402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach !isThumbTwo()) 5137aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 5138aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 51396dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 51406dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 51411e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 51421e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 51438213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 51441e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 51451e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 51461e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 51471e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 5148189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 5149189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 5150189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 5151189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 5152189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 51535b484312c66f8d125c072517947538f301c5a805Jim Grosbachstatic unsigned getRealVSTLNOpcode(unsigned Opc, unsigned &Spacing) { 515484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach switch(Opc) { 515584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach default: assert(0 && "unexpected opcode!"); 51569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // VST1LN 51579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_8: case ARM::VST1LNdWB_fixed_Asm_P8: 51589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I8: case ARM::VST1LNdWB_fixed_Asm_S8: 51599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U8: 51605b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 51619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd8_UPD; 51629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_16: case ARM::VST1LNdWB_fixed_Asm_P16: 51639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I16: case ARM::VST1LNdWB_fixed_Asm_S16: 51649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U16: 51655b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 51669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd16_UPD; 51679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_32: case ARM::VST1LNdWB_fixed_Asm_F: 51689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F32: case ARM::VST1LNdWB_fixed_Asm_I32: 51699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S32: case ARM::VST1LNdWB_fixed_Asm_U32: 51705b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 51719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd32_UPD; 51729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_8: case ARM::VST1LNdWB_register_Asm_P8: 51739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_I8: case ARM::VST1LNdWB_register_Asm_S8: 51749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_U8: 51755b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 51769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd8_UPD; 51779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_16: case ARM::VST1LNdWB_register_Asm_P16: 51789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_I16: case ARM::VST1LNdWB_register_Asm_S16: 51799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_U16: 51805b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 51819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd16_UPD; 51829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_32: case ARM::VST1LNdWB_register_Asm_F: 51839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_F32: case ARM::VST1LNdWB_register_Asm_I32: 51849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_S32: case ARM::VST1LNdWB_register_Asm_U32: 51855b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 51869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd32_UPD; 51879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_8: case ARM::VST1LNdAsm_P8: 51889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_I8: case ARM::VST1LNdAsm_S8: 51899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_U8: 51905b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 51919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd8; 51929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_16: case ARM::VST1LNdAsm_P16: 51939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_I16: case ARM::VST1LNdAsm_S16: 51949b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_U16: 51955b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 51969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd16; 51979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_32: case ARM::VST1LNdAsm_F: 51989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_F32: case ARM::VST1LNdAsm_I32: 51999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_S32: case ARM::VST1LNdAsm_U32: 52005b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST1LNd32; 52029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 52039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // VST2LN 52049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_8: case ARM::VST2LNdWB_fixed_Asm_P8: 52059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_I8: case ARM::VST2LNdWB_fixed_Asm_S8: 52069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_U8: 52075b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd8_UPD; 52099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_16: case ARM::VST2LNdWB_fixed_Asm_P16: 52109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_I16: case ARM::VST2LNdWB_fixed_Asm_S16: 52119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_U16: 52125b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd16_UPD; 52149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_32: case ARM::VST2LNdWB_fixed_Asm_F: 52159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_F32: case ARM::VST2LNdWB_fixed_Asm_I32: 52169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_S32: case ARM::VST2LNdWB_fixed_Asm_U32: 52175b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd32_UPD; 52195b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_16: case ARM::VST2LNqWB_fixed_Asm_P16: 52205b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_I16: case ARM::VST2LNqWB_fixed_Asm_S16: 52215b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_U16: 52225b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 2; 52235b484312c66f8d125c072517947538f301c5a805Jim Grosbach return ARM::VST2LNq16_UPD; 52245b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_32: case ARM::VST2LNqWB_fixed_Asm_F: 52255b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_F32: case ARM::VST2LNqWB_fixed_Asm_I32: 52265b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_S32: case ARM::VST2LNqWB_fixed_Asm_U32: 52275b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 2; 52285b484312c66f8d125c072517947538f301c5a805Jim Grosbach return ARM::VST2LNq32_UPD; 52295b484312c66f8d125c072517947538f301c5a805Jim Grosbach 52309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_8: case ARM::VST2LNdWB_register_Asm_P8: 52319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_I8: case ARM::VST2LNdWB_register_Asm_S8: 52329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_U8: 52335b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd8_UPD; 52359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_16: case ARM::VST2LNdWB_register_Asm_P16: 52369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_I16: case ARM::VST2LNdWB_register_Asm_S16: 52379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_U16: 52385b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd16_UPD; 52409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_32: case ARM::VST2LNdWB_register_Asm_F: 52419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_F32: case ARM::VST2LNdWB_register_Asm_I32: 52429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_S32: case ARM::VST2LNdWB_register_Asm_U32: 52435b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd32_UPD; 52455b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_16: case ARM::VST2LNqWB_register_Asm_P16: 52465b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_I16: case ARM::VST2LNqWB_register_Asm_S16: 52475b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_U16: 52485b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 2; 52495b484312c66f8d125c072517947538f301c5a805Jim Grosbach return ARM::VST2LNq16_UPD; 52505b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_32: case ARM::VST2LNqWB_register_Asm_F: 52515b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_F32: case ARM::VST2LNqWB_register_Asm_I32: 52525b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_S32: case ARM::VST2LNqWB_register_Asm_U32: 52535b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 2; 52545b484312c66f8d125c072517947538f301c5a805Jim Grosbach return ARM::VST2LNq32_UPD; 52555b484312c66f8d125c072517947538f301c5a805Jim Grosbach 52569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_8: case ARM::VST2LNdAsm_P8: 52579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_I8: case ARM::VST2LNdAsm_S8: 52589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_U8: 52595b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd8; 52619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_16: case ARM::VST2LNdAsm_P16: 52629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_I16: case ARM::VST2LNdAsm_S16: 52639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_U16: 52645b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd16; 52669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_32: case ARM::VST2LNdAsm_F: 52679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_F32: case ARM::VST2LNdAsm_I32: 52689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_S32: case ARM::VST2LNdAsm_U32: 52695b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 1; 52709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VST2LNd32; 52715b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_16: case ARM::VST2LNqAsm_P16: 52725b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_I16: case ARM::VST2LNqAsm_S16: 52735b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_U16: 52745b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 2; 52755b484312c66f8d125c072517947538f301c5a805Jim Grosbach return ARM::VST2LNq16; 52765b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_32: case ARM::VST2LNqAsm_F: 52775b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_F32: case ARM::VST2LNqAsm_I32: 52785b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_S32: case ARM::VST2LNqAsm_U32: 52795b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing = 2; 52805b484312c66f8d125c072517947538f301c5a805Jim Grosbach return ARM::VST2LNq32; 528184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 528284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach} 528384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach 528495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbachstatic unsigned getRealVLDLNOpcode(unsigned Opc, unsigned &Spacing) { 52857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach switch(Opc) { 52867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach default: assert(0 && "unexpected opcode!"); 52879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // VLD1LN 52889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_8: case ARM::VLD1LNdWB_fixed_Asm_P8: 52899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I8: case ARM::VLD1LNdWB_fixed_Asm_S8: 52909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U8: 529195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 52929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd8_UPD; 52939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_16: case ARM::VLD1LNdWB_fixed_Asm_P16: 52949b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I16: case ARM::VLD1LNdWB_fixed_Asm_S16: 52959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U16: 529695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 52979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd16_UPD; 52989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_32: case ARM::VLD1LNdWB_fixed_Asm_F: 52999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F32: case ARM::VLD1LNdWB_fixed_Asm_I32: 53009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S32: case ARM::VLD1LNdWB_fixed_Asm_U32: 530195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd32_UPD; 53039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_8: case ARM::VLD1LNdWB_register_Asm_P8: 53049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_I8: case ARM::VLD1LNdWB_register_Asm_S8: 53059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_U8: 530695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd8_UPD; 53089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_16: case ARM::VLD1LNdWB_register_Asm_P16: 53099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_I16: case ARM::VLD1LNdWB_register_Asm_S16: 53109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_U16: 531195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd16_UPD; 53139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_32: case ARM::VLD1LNdWB_register_Asm_F: 53149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_F32: case ARM::VLD1LNdWB_register_Asm_I32: 53159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_S32: case ARM::VLD1LNdWB_register_Asm_U32: 531695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd32_UPD; 53189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_8: case ARM::VLD1LNdAsm_P8: 53199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_I8: case ARM::VLD1LNdAsm_S8: 53209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_U8: 532195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd8; 53239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_16: case ARM::VLD1LNdAsm_P16: 53249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_I16: case ARM::VLD1LNdAsm_S16: 53259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_U16: 532695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd16; 53289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_32: case ARM::VLD1LNdAsm_F: 53299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_F32: case ARM::VLD1LNdAsm_I32: 53309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_S32: case ARM::VLD1LNdAsm_U32: 533195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD1LNd32; 53339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 53349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // VLD2LN 53359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_8: case ARM::VLD2LNdWB_fixed_Asm_P8: 53369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_I8: case ARM::VLD2LNdWB_fixed_Asm_S8: 53379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_U8: 533895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd8_UPD; 53409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_16: case ARM::VLD2LNdWB_fixed_Asm_P16: 53419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_I16: case ARM::VLD2LNdWB_fixed_Asm_S16: 53429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_U16: 534395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd16_UPD; 53459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_32: case ARM::VLD2LNdWB_fixed_Asm_F: 53469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_F32: case ARM::VLD2LNdWB_fixed_Asm_I32: 53479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_S32: case ARM::VLD2LNdWB_fixed_Asm_U32: 534895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd32_UPD; 535095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_fixed_Asm_16: case ARM::VLD2LNqWB_fixed_Asm_P16: 535195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_fixed_Asm_I16: case ARM::VLD2LNqWB_fixed_Asm_S16: 535295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_fixed_Asm_U16: 535395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 535495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return ARM::VLD2LNq16_UPD; 535595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_fixed_Asm_32: case ARM::VLD2LNqWB_fixed_Asm_F: 535695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_fixed_Asm_F32: case ARM::VLD2LNqWB_fixed_Asm_I32: 535795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_fixed_Asm_S32: case ARM::VLD2LNqWB_fixed_Asm_U32: 535895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 2; 535995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return ARM::VLD2LNq32_UPD; 53609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_8: case ARM::VLD2LNdWB_register_Asm_P8: 53619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_I8: case ARM::VLD2LNdWB_register_Asm_S8: 53629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_U8: 536395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd8_UPD; 53659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_16: case ARM::VLD2LNdWB_register_Asm_P16: 53669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_I16: case ARM::VLD2LNdWB_register_Asm_S16: 53679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_U16: 536895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd16_UPD; 53709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_32: case ARM::VLD2LNdWB_register_Asm_F: 53719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_F32: case ARM::VLD2LNdWB_register_Asm_I32: 53729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_S32: case ARM::VLD2LNdWB_register_Asm_U32: 537395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd32_UPD; 537595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_register_Asm_16: case ARM::VLD2LNqWB_register_Asm_P16: 537695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_register_Asm_I16: case ARM::VLD2LNqWB_register_Asm_S16: 537795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_register_Asm_U16: 537895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 2; 537995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return ARM::VLD2LNq16_UPD; 538095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_register_Asm_32: case ARM::VLD2LNqWB_register_Asm_F: 538195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_register_Asm_F32: case ARM::VLD2LNqWB_register_Asm_I32: 538295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqWB_register_Asm_S32: case ARM::VLD2LNqWB_register_Asm_U32: 538395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 2; 538495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return ARM::VLD2LNq32_UPD; 53859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_8: case ARM::VLD2LNdAsm_P8: 53869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_I8: case ARM::VLD2LNdAsm_S8: 53879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_U8: 538895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd8; 53909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_16: case ARM::VLD2LNdAsm_P16: 53919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_I16: case ARM::VLD2LNdAsm_S16: 53929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_U16: 539395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53949b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd16; 53959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_32: case ARM::VLD2LNdAsm_F: 53969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_F32: case ARM::VLD2LNdAsm_I32: 53979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_S32: case ARM::VLD2LNdAsm_U32: 539895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 1; 53999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return ARM::VLD2LNd32; 540095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_16: case ARM::VLD2LNqAsm_P16: 540195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_I16: case ARM::VLD2LNqAsm_S16: 540295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_U16: 540395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 2; 540495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return ARM::VLD2LNq16; 540595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_32: case ARM::VLD2LNqAsm_F: 540695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_F32: case ARM::VLD2LNqAsm_I32: 540795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_S32: case ARM::VLD2LNqAsm_U32: 540895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing = 2; 540995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach return ARM::VLD2LNq32; 54107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 54117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach} 54127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 541383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser:: 5414f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 5415f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 5416f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 54179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // Handle NEON VST complex aliases. 54189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_8: case ARM::VST1LNdWB_register_Asm_P8: 54199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_I8: case ARM::VST1LNdWB_register_Asm_S8: 54209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_U8: case ARM::VST1LNdWB_register_Asm_16: 54219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_P16: case ARM::VST1LNdWB_register_Asm_I16: 54229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_S16: case ARM::VST1LNdWB_register_Asm_U16: 54239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_32: case ARM::VST1LNdWB_register_Asm_F: 54249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_F32: case ARM::VST1LNdWB_register_Asm_I32: 54259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_register_Asm_S32: case ARM::VST1LNdWB_register_Asm_U32: { 542684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 542784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 542884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 54295b484312c66f8d125c072517947538f301c5a805Jim Grosbach unsigned Spacing; 54305b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing)); 543184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 543284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 543384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 543484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rm 543584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 543684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 543784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // CondCode 543884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 543984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 544084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 544184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 54429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 54435b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_register_Asm_8: case ARM::VST2LNdWB_register_Asm_P8: 54445b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_register_Asm_I8: case ARM::VST2LNdWB_register_Asm_S8: 54455b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_register_Asm_U8: case ARM::VST2LNdWB_register_Asm_16: 54469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_P16: case ARM::VST2LNdWB_register_Asm_I16: 54479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_S16: case ARM::VST2LNdWB_register_Asm_U16: 54485b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_register_Asm_32: case ARM::VST2LNdWB_register_Asm_F: 54499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_register_Asm_F32: case ARM::VST2LNdWB_register_Asm_I32: 54505b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_register_Asm_S32: case ARM::VST2LNdWB_register_Asm_U32: 54515b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_16: case ARM::VST2LNqWB_register_Asm_P16: 54525b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_I16: case ARM::VST2LNqWB_register_Asm_S16: 54535b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_U16: case ARM::VST2LNqWB_register_Asm_32: 54545b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_F: case ARM::VST2LNqWB_register_Asm_F32: 54555b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_I32: case ARM::VST2LNqWB_register_Asm_S32: 54565b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_register_Asm_U32: { 54579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach MCInst TmpInst; 54589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // Shuffle the operands around so the lane index operand is in the 54599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // right place. 54605b484312c66f8d125c072517947538f301c5a805Jim Grosbach unsigned Spacing; 54615b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing)); 54629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 54639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 54649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 54659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rm 54669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 54675b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 54685b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing)); 54699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 54709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // CondCode 54719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 54729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach Inst = TmpInst; 54739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return true; 54749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach } 54759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_8: case ARM::VST1LNdWB_fixed_Asm_P8: 54769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I8: case ARM::VST1LNdWB_fixed_Asm_S8: 54779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U8: case ARM::VST1LNdWB_fixed_Asm_16: 54789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P16: case ARM::VST1LNdWB_fixed_Asm_I16: 54799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S16: case ARM::VST1LNdWB_fixed_Asm_U16: 54809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_32: case ARM::VST1LNdWB_fixed_Asm_F: 54819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F32: case ARM::VST1LNdWB_fixed_Asm_I32: 54829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S32: case ARM::VST1LNdWB_fixed_Asm_U32: { 548384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 548484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 548584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 54865b484312c66f8d125c072517947538f301c5a805Jim Grosbach unsigned Spacing; 54875b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing)); 548884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 548984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 549084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 549184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 549284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 549384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 549484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 549584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 549684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 549784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 549884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 54999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 55005b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_8: case ARM::VST2LNdWB_fixed_Asm_P8: 55015b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_I8: case ARM::VST2LNdWB_fixed_Asm_S8: 55025b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_U8: case ARM::VST2LNdWB_fixed_Asm_16: 55039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_P16: case ARM::VST2LNdWB_fixed_Asm_I16: 55049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_S16: case ARM::VST2LNdWB_fixed_Asm_U16: 55055b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_32: case ARM::VST2LNdWB_fixed_Asm_F: 55069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_F32: case ARM::VST2LNdWB_fixed_Asm_I32: 55075b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdWB_fixed_Asm_S32: case ARM::VST2LNdWB_fixed_Asm_U32: 55085b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_16: case ARM::VST2LNqWB_fixed_Asm_P16: 55095b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_I16: case ARM::VST2LNqWB_fixed_Asm_S16: 55105b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_U16: case ARM::VST2LNqWB_fixed_Asm_32: 55115b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_F: case ARM::VST2LNqWB_fixed_Asm_F32: 55125b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_I32: case ARM::VST2LNqWB_fixed_Asm_S32: 55135b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqWB_fixed_Asm_U32: { 55149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach MCInst TmpInst; 55159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // Shuffle the operands around so the lane index operand is in the 55169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // right place. 55175b484312c66f8d125c072517947538f301c5a805Jim Grosbach unsigned Spacing; 55185b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing)); 55199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 55209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 55219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 55229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 55239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 55245b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 55255b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing)); 55269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 55279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 55289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 55299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach Inst = TmpInst; 55309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return true; 55319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach } 55329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_8: case ARM::VST1LNdAsm_P8: case ARM::VST1LNdAsm_I8: 55339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_S8: case ARM::VST1LNdAsm_U8: case ARM::VST1LNdAsm_16: 55349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_P16: case ARM::VST1LNdAsm_I16: case ARM::VST1LNdAsm_S16: 55359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_U16: case ARM::VST1LNdAsm_32: case ARM::VST1LNdAsm_F: 55369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST1LNdAsm_F32: case ARM::VST1LNdAsm_I32: case ARM::VST1LNdAsm_S32: 553784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U32: { 553884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 553984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 554084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 55415b484312c66f8d125c072517947538f301c5a805Jim Grosbach unsigned Spacing; 55425b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing)); 554384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 554484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 554584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 554684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 554784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 554884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 554984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 555084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 555184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 55529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 55535b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdAsm_8: case ARM::VST2LNdAsm_P8: case ARM::VST2LNdAsm_I8: 55545b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdAsm_S8: case ARM::VST2LNdAsm_U8: case ARM::VST2LNdAsm_16: 55559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_P16: case ARM::VST2LNdAsm_I16: case ARM::VST2LNdAsm_S16: 55565b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdAsm_U16: case ARM::VST2LNdAsm_32: case ARM::VST2LNdAsm_F: 55579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VST2LNdAsm_F32: case ARM::VST2LNdAsm_I32: case ARM::VST2LNdAsm_S32: 55585b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNdAsm_U32: case ARM::VST2LNqAsm_16: case ARM::VST2LNqAsm_P16: 55595b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_I16: case ARM::VST2LNqAsm_S16: case ARM::VST2LNqAsm_U16: 55605b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_32: case ARM::VST2LNqAsm_F: case ARM::VST2LNqAsm_F32: 55615b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VST2LNqAsm_I32: case ARM::VST2LNqAsm_S32: case ARM::VST2LNqAsm_U32:{ 55629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach MCInst TmpInst; 55639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // Shuffle the operands around so the lane index operand is in the 55649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // right place. 55655b484312c66f8d125c072517947538f301c5a805Jim Grosbach unsigned Spacing; 55665b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing)); 55679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 55689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 55699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 55705b484312c66f8d125c072517947538f301c5a805Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 55715b484312c66f8d125c072517947538f301c5a805Jim Grosbach Spacing)); 55729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 55739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 55749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 55759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach Inst = TmpInst; 55769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return true; 55779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach } 55789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // Handle NEON VLD complex aliases. 55799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_8: case ARM::VLD1LNdWB_register_Asm_P8: 55809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_I8: case ARM::VLD1LNdWB_register_Asm_S8: 55819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_U8: case ARM::VLD1LNdWB_register_Asm_16: 55829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_P16: case ARM::VLD1LNdWB_register_Asm_I16: 55839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_S16: case ARM::VLD1LNdWB_register_Asm_U16: 55849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_32: case ARM::VLD1LNdWB_register_Asm_F: 55859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_F32: case ARM::VLD1LNdWB_register_Asm_I32: 55869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_register_Asm_S32: case ARM::VLD1LNdWB_register_Asm_U32: { 5587872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach MCInst TmpInst; 5588872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // Shuffle the operands around so the lane index operand is in the 5589872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // right place. 559095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach unsigned Spacing; 559195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing)); 5592872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 5593872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 5594872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 5595872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 5596872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rm 5597872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 5598872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 5599872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // CondCode 5600872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 5601872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach Inst = TmpInst; 5602872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach return true; 5603872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach } 56049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 560595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_register_Asm_8: case ARM::VLD2LNdWB_register_Asm_P8: 560695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_register_Asm_I8: case ARM::VLD2LNdWB_register_Asm_S8: 560795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_register_Asm_U8: case ARM::VLD2LNdWB_register_Asm_16: 56089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_P16: case ARM::VLD2LNdWB_register_Asm_I16: 56099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_S16: case ARM::VLD2LNdWB_register_Asm_U16: 561095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_register_Asm_32: case ARM::VLD2LNdWB_register_Asm_F: 56119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_register_Asm_F32: case ARM::VLD2LNdWB_register_Asm_I32: 561295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_register_Asm_S32: case ARM::VLD2LNdWB_register_Asm_U32: 56135b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_register_Asm_16: case ARM::VLD2LNqWB_register_Asm_P16: 56145b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_register_Asm_I16: case ARM::VLD2LNqWB_register_Asm_S16: 56155b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_register_Asm_U16: case ARM::VLD2LNqWB_register_Asm_32: 56165b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_register_Asm_F: case ARM::VLD2LNqWB_register_Asm_F32: 56175b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_register_Asm_I32: case ARM::VLD2LNqWB_register_Asm_S32: 56185b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_register_Asm_U32: { 56199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach MCInst TmpInst; 56209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // Shuffle the operands around so the lane index operand is in the 56219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // right place. 562295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach unsigned Spacing; 562395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing)); 56249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 562595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 562695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing)); 56279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 56289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 56299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 56309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rm 56319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 563295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 563395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing)); 56349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 56359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // CondCode 56369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 56379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach Inst = TmpInst; 56389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return true; 56399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach } 56409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 56419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_8: case ARM::VLD1LNdWB_fixed_Asm_P8: 56429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I8: case ARM::VLD1LNdWB_fixed_Asm_S8: 56439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U8: case ARM::VLD1LNdWB_fixed_Asm_16: 56449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P16: case ARM::VLD1LNdWB_fixed_Asm_I16: 56459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S16: case ARM::VLD1LNdWB_fixed_Asm_U16: 56469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_32: case ARM::VLD1LNdWB_fixed_Asm_F: 56479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F32: case ARM::VLD1LNdWB_fixed_Asm_I32: 56489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S32: case ARM::VLD1LNdWB_fixed_Asm_U32: { 5649872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach MCInst TmpInst; 5650872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // Shuffle the operands around so the lane index operand is in the 5651872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // right place. 565295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach unsigned Spacing; 565395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing)); 5654872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 5655872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 5656872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 5657872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 5658872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 5659872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 5660872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 5661872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 5662872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 5663872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach Inst = TmpInst; 5664872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach return true; 5665872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach } 56669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 566795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_fixed_Asm_8: case ARM::VLD2LNdWB_fixed_Asm_P8: 566895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_fixed_Asm_I8: case ARM::VLD2LNdWB_fixed_Asm_S8: 566995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_fixed_Asm_U8: case ARM::VLD2LNdWB_fixed_Asm_16: 56709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_P16: case ARM::VLD2LNdWB_fixed_Asm_I16: 56719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_S16: case ARM::VLD2LNdWB_fixed_Asm_U16: 567295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_fixed_Asm_32: case ARM::VLD2LNdWB_fixed_Asm_F: 56739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdWB_fixed_Asm_F32: case ARM::VLD2LNdWB_fixed_Asm_I32: 567495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdWB_fixed_Asm_S32: case ARM::VLD2LNdWB_fixed_Asm_U32: 56755b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_fixed_Asm_16: case ARM::VLD2LNqWB_fixed_Asm_P16: 56765b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_fixed_Asm_I16: case ARM::VLD2LNqWB_fixed_Asm_S16: 56775b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_fixed_Asm_U16: case ARM::VLD2LNqWB_fixed_Asm_32: 56785b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_fixed_Asm_F: case ARM::VLD2LNqWB_fixed_Asm_F32: 56795b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_fixed_Asm_I32: case ARM::VLD2LNqWB_fixed_Asm_S32: 56805b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD2LNqWB_fixed_Asm_U32: { 56819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach MCInst TmpInst; 56829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // Shuffle the operands around so the lane index operand is in the 56839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // right place. 568495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach unsigned Spacing; 568595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing)); 56869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 568795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 568895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing)); 56899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 56909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 56919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 56929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 56939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 569495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 569595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing)); 56969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 56979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 56989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 56999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach Inst = TmpInst; 57009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return true; 57019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach } 57029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 57035b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD1LNdAsm_8: case ARM::VLD1LNdAsm_P8: case ARM::VLD1LNdAsm_I8: 57045b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD1LNdAsm_S8: case ARM::VLD1LNdAsm_U8: case ARM::VLD1LNdAsm_16: 57059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_P16: case ARM::VLD1LNdAsm_I16: case ARM::VLD1LNdAsm_S16: 57065b484312c66f8d125c072517947538f301c5a805Jim Grosbach case ARM::VLD1LNdAsm_U16: case ARM::VLD1LNdAsm_32: case ARM::VLD1LNdAsm_F: 57079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD1LNdAsm_F32: case ARM::VLD1LNdAsm_I32: case ARM::VLD1LNdAsm_S32: 5708dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U32: { 57097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach MCInst TmpInst; 57107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // Shuffle the operands around so the lane index operand is in the 57117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // right place. 571295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach unsigned Spacing; 571395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing)); 57147636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 57157636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 57167636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 57177636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 57187636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 57197636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 57207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 57217636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst = TmpInst; 57227636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return true; 57237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 57249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach 572595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdAsm_8: case ARM::VLD2LNdAsm_P8: case ARM::VLD2LNdAsm_I8: 572695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdAsm_S8: case ARM::VLD2LNdAsm_U8: case ARM::VLD2LNdAsm_16: 57279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_P16: case ARM::VLD2LNdAsm_I16: case ARM::VLD2LNdAsm_S16: 572895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdAsm_U16: case ARM::VLD2LNdAsm_32: case ARM::VLD2LNdAsm_F: 57299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach case ARM::VLD2LNdAsm_F32: case ARM::VLD2LNdAsm_I32: case ARM::VLD2LNdAsm_S32: 573095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNdAsm_U32: case ARM::VLD2LNqAsm_16: case ARM::VLD2LNqAsm_P16: 573195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_I16: case ARM::VLD2LNqAsm_S16: case ARM::VLD2LNqAsm_U16: 573295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_32: case ARM::VLD2LNqAsm_F: case ARM::VLD2LNqAsm_F32: 573395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_I32: case ARM::VLD2LNqAsm_S32: 573495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach case ARM::VLD2LNqAsm_U32: { 57359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach MCInst TmpInst; 57369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // Shuffle the operands around so the lane index operand is in the 57379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach // right place. 573895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach unsigned Spacing; 573995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing)); 57409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 574195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 574295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing)); 57439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 57449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 57459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 574695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 574795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach Spacing)); 57489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 57499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 57509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 57519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach Inst = TmpInst; 57529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach return true; 57539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach } 5754863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach // Handle the Thumb2 mode MOV complex aliases. 57552cc5cda464e7c936215281934193658cb799c603Jim Grosbach case ARM::t2MOVsr: 57562cc5cda464e7c936215281934193658cb799c603Jim Grosbach case ARM::t2MOVSsr: { 57572cc5cda464e7c936215281934193658cb799c603Jim Grosbach // Which instruction to expand to depends on the CCOut operand and 57582cc5cda464e7c936215281934193658cb799c603Jim Grosbach // whether we're in an IT block if the register operands are low 57592cc5cda464e7c936215281934193658cb799c603Jim Grosbach // registers. 57602cc5cda464e7c936215281934193658cb799c603Jim Grosbach bool isNarrow = false; 57612cc5cda464e7c936215281934193658cb799c603Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 57622cc5cda464e7c936215281934193658cb799c603Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 57632cc5cda464e7c936215281934193658cb799c603Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg()) && 57642cc5cda464e7c936215281934193658cb799c603Jim Grosbach Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && 57652cc5cda464e7c936215281934193658cb799c603Jim Grosbach inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr)) 57662cc5cda464e7c936215281934193658cb799c603Jim Grosbach isNarrow = true; 57672cc5cda464e7c936215281934193658cb799c603Jim Grosbach MCInst TmpInst; 57682cc5cda464e7c936215281934193658cb799c603Jim Grosbach unsigned newOpc; 57692cc5cda464e7c936215281934193658cb799c603Jim Grosbach switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) { 57702cc5cda464e7c936215281934193658cb799c603Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 57712cc5cda464e7c936215281934193658cb799c603Jim Grosbach case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break; 57722cc5cda464e7c936215281934193658cb799c603Jim Grosbach case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break; 57732cc5cda464e7c936215281934193658cb799c603Jim Grosbach case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break; 57742cc5cda464e7c936215281934193658cb799c603Jim Grosbach case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break; 57752cc5cda464e7c936215281934193658cb799c603Jim Grosbach } 57762cc5cda464e7c936215281934193658cb799c603Jim Grosbach TmpInst.setOpcode(newOpc); 57772cc5cda464e7c936215281934193658cb799c603Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 57782cc5cda464e7c936215281934193658cb799c603Jim Grosbach if (isNarrow) 57792cc5cda464e7c936215281934193658cb799c603Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg( 57802cc5cda464e7c936215281934193658cb799c603Jim Grosbach Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0)); 57812cc5cda464e7c936215281934193658cb799c603Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 57822cc5cda464e7c936215281934193658cb799c603Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rm 57832cc5cda464e7c936215281934193658cb799c603Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 57842cc5cda464e7c936215281934193658cb799c603Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 57852cc5cda464e7c936215281934193658cb799c603Jim Grosbach if (!isNarrow) 57862cc5cda464e7c936215281934193658cb799c603Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg( 57872cc5cda464e7c936215281934193658cb799c603Jim Grosbach Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0)); 57882cc5cda464e7c936215281934193658cb799c603Jim Grosbach Inst = TmpInst; 57892cc5cda464e7c936215281934193658cb799c603Jim Grosbach return true; 57902cc5cda464e7c936215281934193658cb799c603Jim Grosbach } 5791863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach case ARM::t2MOVsi: 5792863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach case ARM::t2MOVSsi: { 5793863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach // Which instruction to expand to depends on the CCOut operand and 5794863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach // whether we're in an IT block if the register operands are low 5795863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach // registers. 5796863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach bool isNarrow = false; 5797863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 5798863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 5799863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi)) 5800863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach isNarrow = true; 5801863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach MCInst TmpInst; 5802863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach unsigned newOpc; 5803863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) { 5804863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 5805863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break; 5806863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break; 5807863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break; 5808863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break; 5809520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break; 5810863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach } 5811863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach unsigned Ammount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()); 5812863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach if (Ammount == 32) Ammount = 0; 5813863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach TmpInst.setOpcode(newOpc); 5814863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 5815863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach if (isNarrow) 5816863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg( 5817863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0)); 5818863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 5819520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach if (newOpc != ARM::t2RRX) 5820520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Ammount)); 5821863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // CondCode 5822863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 5823863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach if (!isNarrow) 5824863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg( 5825863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0)); 5826863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach Inst = TmpInst; 5827863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach return true; 5828863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach } 5829863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach // Handle the ARM mode MOV complex aliases. 583023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::ASRr: 583123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSRr: 583223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSLr: 583323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::RORr: { 583423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 583523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach switch(Inst.getOpcode()) { 583623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 583723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::ASRr: ShiftTy = ARM_AM::asr; break; 583823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSRr: ShiftTy = ARM_AM::lsr; break; 583923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSLr: ShiftTy = ARM_AM::lsl; break; 584023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::RORr: ShiftTy = ARM_AM::ror; break; 584123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach } 584223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0); 584323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach MCInst TmpInst; 584423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.setOpcode(ARM::MOVsr); 584523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 584623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 584723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rm 584823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 584923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // CondCode 585023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 585123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // cc_out 585223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach Inst = TmpInst; 585323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach return true; 585423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach } 5855ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::ASRi: 5856ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSRi: 5857ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSLi: 5858ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::RORi: { 5859ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 5860ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach switch(Inst.getOpcode()) { 5861ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 5862ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::ASRi: ShiftTy = ARM_AM::asr; break; 5863ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSRi: ShiftTy = ARM_AM::lsr; break; 5864ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSLi: ShiftTy = ARM_AM::lsl; break; 5865ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::RORi: ShiftTy = ARM_AM::ror; break; 5866ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach } 5867ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach // A shift by zero is a plain MOVr, not a MOVsi. 586848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach unsigned Amt = Inst.getOperand(2).getImm(); 5869ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi; 5870ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt); 587171810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach MCInst TmpInst; 5872ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach TmpInst.setOpcode(Opc); 587371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 587471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 5875ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (Opc == ARM::MOVsi) 5876ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 587771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // CondCode 587871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 587971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // cc_out 588071810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach Inst = TmpInst; 588183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 588271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach } 588348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach case ARM::RRXi: { 588448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0); 588548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach MCInst TmpInst; 588648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.setOpcode(ARM::MOVsi); 588748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 588848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 588948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 589048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 589148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 589248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // cc_out 589348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach Inst = TmpInst; 589448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach return true; 589548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach } 58960352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach case ARM::t2LDMIA_UPD: { 58970352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // If this is a load of a single register, then we should use 58980352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 58990352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach if (Inst.getNumOperands() != 5) 59000352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return false; 59010352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach MCInst TmpInst; 59020352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.setOpcode(ARM::t2LDR_POST); 59030352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 59040352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 59050352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 59060352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 59070352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 59080352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 59090352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach Inst = TmpInst; 59100352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return true; 59110352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach } 59120352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach case ARM::t2STMDB_UPD: { 59130352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // If this is a store of a single register, then we should use 59140352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 59150352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach if (Inst.getNumOperands() != 5) 59160352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return false; 59170352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach MCInst TmpInst; 59180352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.setOpcode(ARM::t2STR_PRE); 59190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 59200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 59210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 59220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 59230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 59240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 59250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach Inst = TmpInst; 59260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return true; 59270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach } 5928f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 5929f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 5930f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 5931f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 5932f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 5933f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 5934f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 5935f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 5936f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 5937f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 5938f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 5939f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 5940f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 5941f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5942f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 594383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 5944f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 5945f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 5946f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 5947f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 5948f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 5949f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 5950f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 5951f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 5952f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 5953f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 5954f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 5955f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 5956f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 5957f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 5958f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5959f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 5960f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 5961f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 5962da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach case ARM::t2ADDri12: 5963da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // If the immediate fits for encoding T3 (t2ADDri) and the generic "add" 5964da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // mnemonic was used (not "addw"), encoding T3 is preferred. 5965da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" || 5966da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 5967da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5968da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.setOpcode(ARM::t2ADDri); 5969da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 5970da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5971da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach case ARM::t2SUBri12: 5972da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub" 5973da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // mnemonic was used (not "subw"), encoding T3 is preferred. 5974da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" || 5975da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 5976da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5977da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.setOpcode(ARM::t2SUBri); 5978da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 5979da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 598089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 59810f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 59820f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 59830f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 59840f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 598583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 598689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 598783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 598883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 598989e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 5990f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 5991f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 5992f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 5993f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 5994f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 599583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 5996f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 599783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 599883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 5999f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 6000927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach case ARM::t2ADDrr: { 6001927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // If the destination and first source operand are the same, and 6002927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // there's no setting of the flags, use encoding T2 instead of T3. 6003927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // Note that this is only for ADD, not SUB. This mirrors the system 6004927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // 'as' behaviour. Make sure the wide encoding wasn't explicit. 6005927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() || 6006927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach Inst.getOperand(5).getReg() != 0 || 6007713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 6008713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == ".w")) 6009927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach break; 6010927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach MCInst TmpInst; 6011927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.setOpcode(ARM::tADDhirr); 6012927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 6013927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 6014927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 6015927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 6016927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 6017927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach Inst = TmpInst; 6018927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach return true; 6019927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach } 602051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 602151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 602283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) { 602351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 602483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 602583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 602651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 602751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 602851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 602983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){ 603051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 603183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 603283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 603351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 6034c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 6035a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 603683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) { 6037c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 603883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 603983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 6040c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 6041395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 6042395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 604383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) { 6044395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 604583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 604683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 60473ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 604876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 604976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 605076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 605176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 605276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 605376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 605476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 605576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 605676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 605776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 605876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 605976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 606076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 606176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 606276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 606376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 606476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 606576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 606676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 606776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 606876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 606983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 607076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 607176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 607276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 60738213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 60748213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 60758213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 60768213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 60778213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 60788213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 60798213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 60808213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 60818213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 60828213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 608383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 60848213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 60858213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 60868213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 60875402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach case ARM::tPOP: { 60885402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach bool listContainsBase; 60895402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // If the register list contains any high registers, we need to use 60905402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 60915402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // should have generated an error in validateInstruction(). 60925402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase)) 609383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 60945402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach assert (isThumbTwo()); 60955402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.setOpcode(ARM::t2LDMIA_UPD); 60965402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Add the base register and writeback operands. 60975402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 60985402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 609983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 61005402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach } 61015402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach case ARM::tPUSH: { 61025402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach bool listContainsBase; 61035402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase)) 610483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 61055402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach assert (isThumbTwo()); 61065402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.setOpcode(ARM::t2STMDB_UPD); 61075402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Add the base register and writeback operands. 61085402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 61095402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 611083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 61115402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach } 61121ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 61131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 61141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 61151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 61161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 6117c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 6118c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 6119c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 61201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 61211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 61221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 61231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 61241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 61251ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 61261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 61271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 61281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 61291ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 61301ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 613183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 61321ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 61331ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 61341ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 61351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 61361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 61371ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 61381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 61391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 61401ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 61411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 61421ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 61431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 61441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 61451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 61461ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 61471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 61481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 61491ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 61501ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 61511ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 615283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 61531ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 61541ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 61551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 6156326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 615750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 615850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 615950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 6160326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 6161326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 6162326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 6163326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 6164326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 6165326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 6166326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 616750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 616850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 616950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 617050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 617150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 617250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 617350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 617450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 6175326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 6176326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 6177326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 6178326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 6179326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 6180326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 6181326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 6182326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 618383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 6184326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 6185326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 6186326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 618704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach case ARM::MOVsi: { 618804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm()); 618904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach if (SOpc == ARM_AM::rrx) return false; 619004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) { 619104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach // Shifting by zero is accepted as a vanilla 'MOVr' 619204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach MCInst TmpInst; 619304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach TmpInst.setOpcode(ARM::MOVr); 619404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 619504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 619604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 619704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 619804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 619904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach Inst = TmpInst; 620004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach return true; 620104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach } 620204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach return false; 620304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach } 62048d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::ANDrsi: 62058d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::ORRrsi: 62068d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::EORrsi: 62078d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::BICrsi: 62088d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::SUBrsi: 62098d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::ADDrsi: { 62108d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach unsigned newOpc; 62118d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm()); 62128d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach if (SOpc == ARM_AM::rrx) return false; 62138d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach switch (Inst.getOpcode()) { 62148d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach default: assert("unexpected opcode!"); 62158d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::ANDrsi: newOpc = ARM::ANDrr; break; 62168d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::ORRrsi: newOpc = ARM::ORRrr; break; 62178d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::EORrsi: newOpc = ARM::EORrr; break; 62188d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::BICrsi: newOpc = ARM::BICrr; break; 62198d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::SUBrsi: newOpc = ARM::SUBrr; break; 62208d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach case ARM::ADDrsi: newOpc = ARM::ADDrr; break; 62218d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach } 62228d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach // If the shift is by zero, use the non-shifted instruction definition. 62238d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0) { 62248d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach MCInst TmpInst; 62258d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach TmpInst.setOpcode(newOpc); 62268d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 62278d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 62288d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 62298d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 62308d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 62318d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 62328d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach Inst = TmpInst; 62338d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach return true; 62348d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach } 62358d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach return false; 62368d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach } 623789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 623889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 623989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 624089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 624189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 624289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 624389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 624489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 624589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 6246f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 6247f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 624889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 624989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 625089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 625189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 625289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 625389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 625489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 6255f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 6256f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 6257f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 6258f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 6259f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 6260f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 6261f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 6262f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 626389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 626489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 6265f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 626683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 6267f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 6268f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 626947a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 627047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 627147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 6272194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 62731a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCInstrDesc &MCID = getInstDesc(Opc); 627447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 627547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 627647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 627747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 627847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 627947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 628047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 628147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 628247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 628347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 628447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 628547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 628647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 628747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 628847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 628947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 6290f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 6291f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 629247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 6293f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 6294f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 6295f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 629647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 6297194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 6298194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 6299194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 6300194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 6301194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 6302194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 6303194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 63044ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 6305194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 6306194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 6307194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 630847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 630947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 631047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 6311fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 6312fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 6313fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 6314fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 6315fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 6316fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 631719cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 6318193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 6319193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 632019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 6321e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 6322189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 6323189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 6324a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 6325a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 6326a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 6327a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 6328189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 6329a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 6330189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 6331f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 633283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // encoding is selected. Loop on it while changes happen so the 633383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // individual transformations can chain off each other. E.g., 633483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8) 633583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach while (processInstruction(Inst, Operands)) 633683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach ; 6337f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 6338a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 6339a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 6340a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 6341a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 6342a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 6343fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 6344fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 6345e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 6346e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 6347e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 6348e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 6349e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 6350e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 6351e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 6352e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 635316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 6354e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 6355e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 6356e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 635716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 6358e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 6359e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 6360e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 636147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 6362b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 636388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 636488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 6365f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 6366f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 636747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 636847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 6369194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 6370194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 6371194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 6372194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 6373fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 637416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 6375c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 6376146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 6377fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 6378fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 63791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 6380ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 6381ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 6382ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 63831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 6384515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 63851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 63869a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach else if (IDVal == ".arm") 63879a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return parseDirectiveARM(DirectiveID.getLoc()); 6388515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 63891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 6390515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 63911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 6392515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 63931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 6394a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach else if (IDVal == ".unreq") 6395a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return parseDirectiveUnreq(DirectiveID.getLoc()); 6396d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim else if (IDVal == ".arch") 6397d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim return parseDirectiveArch(DirectiveID.getLoc()); 6398d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim else if (IDVal == ".eabi_attribute") 6399d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim return parseDirectiveEabiAttr(DirectiveID.getLoc()); 6400ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 6401ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 6402ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 64031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 6404ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 64051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 6406ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 6407ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 6408ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 6409ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 6410ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 6411ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 6412aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 6413ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 6414ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 6415ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 641616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 6417ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 6418ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 6419ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 6420b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 6421ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 6422ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 6423ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 6424b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 6425ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 6426ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 6427ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 64281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 6429515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 64301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 6431515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 6432515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 6433b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 6434515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 64359a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (!isThumb()) 64369a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach SwitchMode(); 64379a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 64389a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return false; 64399a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach} 64409a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach 64419a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM 64429a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// ::= .arm 64439a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) { 64449a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) 64459a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return Error(L, "unexpected token in directive"); 64469a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach Parser.Lex(); 64479a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach 64489a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (isThumb()) 64499a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach SwitchMode(); 64509a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 6451515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 6452515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 6453515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 64541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 6455515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 64561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 64576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 64586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 64596469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 6460de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach bool needFuncName = true; 64616469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 6462de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach // Darwin asm has (optionally) function name after .thumb_func direction 64636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 64646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 64656469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 6466de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach if (Tok.isNot(AsmToken::EndOfStatement)) { 6467de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 6468de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach return Error(L, "unexpected token in .thumb_func directive"); 6469de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach Name = Tok.getIdentifier(); 6470de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach Parser.Lex(); // Consume the identifier token. 6471de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach needFuncName = false; 6472de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach } 64736469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 64746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 6475de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) 6476515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 6477de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach 6478de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach // Eat the end of statement and any blank lines that follow. 6479de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach while (getLexer().is(AsmToken::EndOfStatement)) 6480de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach Parser.Lex(); 6481515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 64826469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 6483de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach // We really should be checking the next symbol definition even if there's 6484de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach // stuff in between. 6485de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach if (needFuncName) { 6486d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach Name = Parser.getTok().getIdentifier(); 64876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 64886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 6489642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 6490642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 6491642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 6492515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 6493515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 6494515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 64951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 6496515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 64971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 649818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 6499515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 6500515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 650138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 650258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 6503b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 650458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 65059e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 6506515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 6507515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 6508515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 6509515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 651018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 6511b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 6512515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 6513515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 6514515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 6515515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 6516515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 6517515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 65181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 6519515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 65201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 652118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 6522515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 6523515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 652418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 652558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 6526b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 652758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 6528b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 6529515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 6530515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 6531515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 6532515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 653318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 6534b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 6535515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 653632869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 653798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 6538ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 653998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 654032869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 654198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 6542ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 654398447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 6544eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 65452a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 6546515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 6547515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 6548515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 6549a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveReq 6550a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// ::= name .req registername 6551a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { 6552a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach Parser.Lex(); // Eat the '.req' token. 6553a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach unsigned Reg; 6554a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach SMLoc SRegLoc, ERegLoc; 6555a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach if (ParseRegister(Reg, SRegLoc, ERegLoc)) { 6556a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach Parser.EatToEndOfStatement(); 6557a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return Error(SRegLoc, "register name expected"); 6558a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach } 6559a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach 6560a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach // Shouldn't be anything else. 6561a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 6562a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach Parser.EatToEndOfStatement(); 6563a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return Error(Parser.getTok().getLoc(), 6564a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach "unexpected input in .req directive."); 6565a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach } 6566a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach 6567a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach Parser.Lex(); // Consume the EndOfStatement 6568a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach 6569a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg) 6570a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return Error(SRegLoc, "redefinition of '" + Name + 6571a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach "' does not match original."); 6572a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach 6573a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return false; 6574a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach} 6575a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach 6576a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveUneq 6577a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// ::= .unreq registername 6578a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveUnreq(SMLoc L) { 6579a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach if (Parser.getTok().isNot(AsmToken::Identifier)) { 6580a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach Parser.EatToEndOfStatement(); 6581a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return Error(L, "unexpected input in .unreq directive."); 6582a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach } 6583a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach RegisterReqs.erase(Parser.getTok().getIdentifier()); 6584a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach Parser.Lex(); // Eat the identifier. 6585a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach return false; 6586a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach} 6587a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach 6588d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveArch 6589d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// ::= .arch token 6590d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveArch(SMLoc L) { 6591d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim return true; 6592d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim} 6593d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim 6594d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveEabiAttr 6595d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// ::= .eabi_attribute int, int 6596d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) { 6597d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim return true; 6598d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim} 6599d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim 660090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 660190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 66029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 6603ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 660494b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 660594b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 660690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 6607ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 66083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 66090692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 66100692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 66113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 6612