ARMAsmParser.cpp revision d7ea73a4909fc3200a1cecd2b420d7ace2180b70
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// The LLVM Compiler Infrastructure 4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source 6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details. 7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===// 9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h" 2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h" 23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 2589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach#include "llvm/Support/MathExtras.h" 26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 28fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h" 3075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h" 32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 33345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 34c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 4116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbachenum VectorLaneTy { NoLanes, AllLanes, IndexedLane }; 4398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 4494b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 45ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 48f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach struct { 49f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes Cond; // Condition for IT block. 50f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Mask:4; // Condition mask for instructions. 51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Starting at first 1 (from lsb). 52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '1' condition as indicated in IT. 53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '0' inverse of condition (else). 54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Count of instructions in IT block is 55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // 4 - trailingzeroes(mask) 56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool FirstCond; // Explicit flag for when we're parsing the 58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // First instruction in the IT block. It's 59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // implied in the mask, so needs special 60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // handling. 61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned CurPosition; // Current position in parsing of IT 63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // block. In range [0,3]. Initialized 64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // according to count of instructions in block. 65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // ~0U if no active IT block. 66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } ITState; 67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool inITBlock() { return ITState.CurPosition != ~0U;} 68a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach void forwardITPosition() { 69a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (!inITBlock()) return; 70a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Move to the next instruction in the IT block, if there is one. If not, 71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // mark the block as done. 72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach unsigned TZ = CountTrailingZeros_32(ITState.Mask); 73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (++ITState.CurPosition == 5 - TZ) 74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach ITState.CurPosition = ~0U; // Done with the IT block after this. 75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 76f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 77f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 78ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 79ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 860d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 959a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach bool parseDirectiveARM(SMLoc L); 961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 99515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 10189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool &CarrySetting, unsigned &ProcessorIMod, 10289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask); 1031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 104fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 10516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 106ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 107ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 108ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 109ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 110ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 111ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 112ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 11347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 11447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 11547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 116194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 117194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 118194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 119acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool hasV7Ops() const { 120acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::HasV7Ops; 121acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 12232869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 123ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 124ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 12532869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 126acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool isMClass() const { 127acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::FeatureMClass; 128acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 129ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1330692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 136a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 13889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 13943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 140f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 14143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 142f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 1439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OperandMatchResultTy parseCoprocOptionOperand( 1449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 14543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1468bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1488bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1508bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 155f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 156f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 157f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 158f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 159c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 160580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 162293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 164251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 1659d39036f62674606565217a10db28171b9594bc7Jim Grosbach OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 166862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&); 1677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index); 168ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 169ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 170a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 171a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 172a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 173a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 174eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 175eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 176ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 177ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 179ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1809ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 1819ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &); 182548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 183548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 185ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1867b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1877b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 19914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 200623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 201623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 20388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20412431329d617064d6e72dd040a58c1635cc261abJim Grosbach bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, 20512431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20612431329d617064d6e72dd040a58c1635cc261abJim Grosbach bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, 20712431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2084334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, 2094334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2104334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, 2114334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 212189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 213189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 214189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 21583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach bool processInstruction(MCInst &Inst, 216f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 217d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 218d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 219189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 220ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 22147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 222194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 223f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Match_RequiresNotITBlock, 224194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 225194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 22647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 22747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 228ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 22994b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 230ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 23132869205052430f45d598fba25ab878d8b29da2dEvan Cheng 232ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 233ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 234f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 235f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Not in an ITBlock to start with. 236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = ~0U; 237ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 238ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 2401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 2411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 242189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 2431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 2441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 24547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 24647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 2471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 2481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 250ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 25116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 25216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2533a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 2543a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 255a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 256a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 257146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CondCode, 26021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CCOut, 26121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ITCondMask, 26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocNum, 26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocReg, 2649b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach k_CoprocOption, 26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Immediate, 26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_FPImmediate, 26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MemBarrierOpt, 26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Memory, 26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_PostIndexRegister, 27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MSRMask, 27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ProcIFlags, 272460a90540b045c102012da2492999557e6840526Jim Grosbach k_VectorIndex, 27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Register, 27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RegisterList, 27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_DPRRegisterList, 27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_SPRRegisterList, 277862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach k_VectorList, 27898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach k_VectorListAllLanes, 2797636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach k_VectorListIndexed, 28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedRegister, 28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedImmediate, 28221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShifterImmediate, 28321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RotateImmediate, 28421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_BitfieldDescriptor, 28521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Token 286a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 287a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 28924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 290a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 297fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 298fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 299fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 300fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 3019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach unsigned Val; 3029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } CoprocOption; 3039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 3049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach struct { 30589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 30689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 30789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 30889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 30989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 31089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 31189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 31289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 313a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 314a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 315a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 326a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 327a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 329862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // A vector register list is a sequential list of 1 to 4 registers. 330862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach struct { 331862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned RegNum; 332862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count; 3337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned LaneIndex; 334862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } VectorList; 335862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 3368155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 337460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned Val; 338460a90540b045c102012da2492999557e6840526Jim Grosbach } VectorIndex; 339460a90540b045c102012da2492999557e6840526Jim Grosbach 340460a90540b045c102012da2492999557e6840526Jim Grosbach struct { 341cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 342cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 34316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3449d39036f62674606565217a10db28171b9594bc7Jim Grosbach struct { 3459d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned Val; // encoded 8-bit representation 3469d39036f62674606565217a10db28171b9594bc7Jim Grosbach } FPImm; 3479d39036f62674606565217a10db28171b9594bc7Jim Grosbach 3486a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 349a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 350a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 3517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 3527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 3537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 3547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 3557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 35657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned ShiftImm; // shift for OffsetReg. 35757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment; // 0 = no alignment specified 35857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // n = alignment in bytes (8, 16, or 32) 3597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 360e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach } Memory; 3610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 3620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 3637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 364f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 365f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 366f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 3677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 3687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 370580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 371e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 372580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 373e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 374e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 375e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 376e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 377e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 378af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 37992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 38092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 38192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 38292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 383af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 3847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 3857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 387293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 388293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 389293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 390293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 391a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 39216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 393146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 394146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 395762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 396762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 397762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 398762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 399762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 40021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 4018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 4028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 40321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: 40489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 40589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 4078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 408762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 40921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 41021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 411762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 412762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 41321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 41521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: 41624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 4178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 418862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 41998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case k_VectorListAllLanes: 4207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case k_VectorListIndexed: 421862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach VectorList = o.VectorList; 422862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 42321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 42421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 425fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 426fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 4279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 4289b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach CoprocOption = o.CoprocOption; 4299b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 43021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 431762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 43321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 4349d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImm = o.FPImm; 4359d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 43621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 437706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 438706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 440e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory = o.Memory; 441762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 44221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 4437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 4447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 44521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 446584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 447584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 44821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: 449a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 4500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 45121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 4530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 455af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 45721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 458af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 45992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 46021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 4617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 4627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 46321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 464293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 465293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 466460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 467460a90540b045c102012da2492999557e6840526Jim Grosbach VectorIndex = o.VectorIndex; 468460a90540b045c102012da2492999557e6840526Jim Grosbach break; 469762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 470762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 47116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 472762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 47821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_CondCode && "Invalid access!"); 4798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 4808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 482fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 48321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 484fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 485fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 486fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 48821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Token && "Invalid access!"); 489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 4947729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4975fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind == k_SPRRegisterList) && "Invalid access!"); 50024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 5018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 5028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 503cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 50421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Immediate && "Invalid access!"); 505cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 506cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 507cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 5089d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned getFPImm() const { 50921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_FPImmediate && "Invalid access!"); 5109d39036f62674606565217a10db28171b9594bc7Jim Grosbach return FPImm.Val; 5119d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 5129d39036f62674606565217a10db28171b9594bc7Jim Grosbach 513460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned getVectorIndex() const { 514460a90540b045c102012da2492999557e6840526Jim Grosbach assert(Kind == k_VectorIndex && "Invalid access!"); 515460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val; 516460a90540b045c102012da2492999557e6840526Jim Grosbach } 517460a90540b045c102012da2492999557e6840526Jim Grosbach 518706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 51921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MemBarrierOpt && "Invalid access!"); 520706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 521706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 522706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_ProcIFlags && "Invalid access!"); 525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 527a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 528584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MSRMask && "Invalid access!"); 530584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 531584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 532584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 53321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocNum() const { return Kind == k_CoprocNum; } 53421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocReg() const { return Kind == k_CoprocReg; } 5359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach bool isCoprocOption() const { return Kind == k_CoprocOption; } 53621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCondCode() const { return Kind == k_CondCode; } 53721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCCOut() const { return Kind == k_CCOut; } 53821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITMask() const { return Kind == k_ITCondMask; } 53921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITCondCode() const { return Kind == k_CondCode; } 54021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isImm() const { return Kind == k_Immediate; } 54121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isFPImm() const { return Kind == k_FPImmediate; } 542a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isImm8s4() const { 54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 544a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 545a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 546a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!CE) return false; 547a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Value = CE->getValue(); 548a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 549a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 55072f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 55121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 55272f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 55372f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 55472f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 55572f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 55672f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 55772f39f8436848885176943b0ba985a7171145423Jim Grosbach } 55872f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 55921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 56072f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 56172f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 56272f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 56372f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 56472f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 56572f39f8436848885176943b0ba985a7171145423Jim Grosbach } 5666b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 56721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5706b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5716b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 5736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 574587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach bool isImm0_1() const { 575587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (Kind != k_Immediate) 576587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return false; 577587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 578587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (!CE) return false; 579587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach int64_t Value = CE->getValue(); 580587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return Value >= 0 && Value < 2; 581587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach } 582587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach bool isImm0_3() const { 583587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (Kind != k_Immediate) 584587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return false; 585587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 586587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach if (!CE) return false; 587587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach int64_t Value = CE->getValue(); 588587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach return Value >= 0 && Value < 4; 589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach } 59083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 59121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 59283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 59383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 59483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 59583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 59683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 59783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 59883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 59921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 60083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 60183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 60283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 60383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 60483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 6067c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 60721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6087c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 6097c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6107c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 6117c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 6127c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 6137c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 614730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach bool isImm0_63() const { 615730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach if (Kind != k_Immediate) 616730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach return false; 617730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 618730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach if (!CE) return false; 619730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach int64_t Value = CE->getValue(); 620730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach return Value >= 0 && Value < 64; 621730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach } 6223b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm8() const { 6233b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6243b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6253b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6263b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6273b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6283b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value == 8; 6293b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6303b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm16() const { 6313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6323b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6343b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6353b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6363b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value == 16; 6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm32() const { 6393b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6403b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6413b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6423b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6433b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6443b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value == 32; 6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6466b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm8() const { 6476b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6486b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6496b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6506b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6516b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6526b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 8; 6536b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm16() const { 6556b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6566b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6576b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6586b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6596b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6606b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 16; 6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm32() const { 6636b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6646b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6656b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6666b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6676b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6686b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 32; 6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6706b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach bool isShrImm64() const { 6716b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (Kind != k_Immediate) 6726b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return false; 6736b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6746b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach if (!CE) return false; 6756b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach int64_t Value = CE->getValue(); 6766b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach return Value > 0 && Value <= 64; 6776b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach } 6783b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_7() const { 6793b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6803b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6813b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6823b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6833b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6843b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value > 0 && Value < 8; 6853b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_15() const { 6873b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6883b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6893b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6903b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6913b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 6923b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value > 0 && Value < 16; 6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach bool isImm1_31() const { 6953b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (Kind != k_Immediate) 6963b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return false; 6973b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6983b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach if (!CE) return false; 6993b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach int64_t Value = CE->getValue(); 7003b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach return Value > 0 && Value < 32; 7013b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach } 702f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 70321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 704f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 705f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 706f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 707f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 708f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 709f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 71121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 7124a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 7134a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 7154a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 7164a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 7174a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 718ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach bool isImm0_32() const { 719ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (Kind != k_Immediate) 720ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach return false; 721ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 722ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (!CE) return false; 723ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach int64_t Value = CE->getValue(); 724ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach return Value >= 0 && Value < 33; 725ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach } 726fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 72721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 728fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 729fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 730fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 731fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 732fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 733fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 734ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 73521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 736ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 737ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 738ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 739ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 740ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 741ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 742ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 743ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 744ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 74521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 746ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 747ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 748ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 749ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 750ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 751ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 75270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 75321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 75470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 75570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 75670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 75770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 75870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 75970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 76121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 766f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 767f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 768f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 76921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 770f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 771f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 772f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 773f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 774f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 775f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 7766bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 77721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 7786bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 7796bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7806bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 7816bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 7826bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 7836bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 784e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach bool isARMSOImmNot() const { 785e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach if (Kind != k_Immediate) 786e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach return false; 787e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 788e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach if (!CE) return false; 789e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach int64_t Value = CE->getValue(); 790e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach return ARM_AM::getSOImmVal(~Value) != -1; 791e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach } 7923bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach bool isARMSOImmNeg() const { 7933bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (Kind != k_Immediate) 7943bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return false; 7953bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7963bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (!CE) return false; 7973bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach int64_t Value = CE->getValue(); 7983bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return ARM_AM::getSOImmVal(-Value) != -1; 7993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 8006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 80121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 8026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 8036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 8056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 8066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 8076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 80889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach bool isT2SOImmNot() const { 80989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach if (Kind != k_Immediate) 81089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach return false; 81189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 81289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach if (!CE) return false; 81389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach int64_t Value = CE->getValue(); 81489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach return ARM_AM::getT2SOImmVal(~Value) != -1; 81589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach } 8163bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach bool isT2SOImmNeg() const { 8173bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (Kind != k_Immediate) 8183bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return false; 8193bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8203bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach if (!CE) return false; 8213bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach int64_t Value = CE->getValue(); 8223bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach return ARM_AM::getT2SOImmVal(-Value) != -1; 8233bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 824c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 82521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 826c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 827c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 828c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 829c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 830c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 831c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 83221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isReg() const { return Kind == k_Register; } 83321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegList() const { return Kind == k_RegisterList; } 83421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 83521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 83621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isToken() const { return Kind == k_Token; } 83721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 83821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemory() const { return Kind == k_Memory; } 83921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isShifterImm() const { return Kind == k_ShifterImmediate; } 84021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 84121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 84221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRotImm() const { return Kind == k_RotateImmediate; } 84321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 84421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 845f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 846430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift; 847f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 84857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isMemNoOffset(bool alignOK = false) const { 849f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 850ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 8517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 85257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 && 85357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach (alignOK || Memory.Alignment == 0); 85457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 85557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isAlignedMemory() const { 85657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return isMemNoOffset(true); 857ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 85957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 861e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 8627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 863e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 864e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 8667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 867039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 86821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 869039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 870039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 871039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 872039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 873039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 874039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 875039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 8762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 87757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 8782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 879e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::no_shift) return false; 8802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 881e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 8822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 883e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 884e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 8862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 88821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate && Kind != k_PostIndexRegister) 8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 89021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) 8912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 8952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 896251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 897251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 8982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 8997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 900681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // If we have an immediate that's not a constant, treat it as a label 901681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // reference needing a fixup. If it is a constant, it's something else 902681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // and we reject it. 903681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 904681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach return true; 90557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 9067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 907e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return false; 9087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 909e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 910e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 9110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 912681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Val == INT32_MIN; 9137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 9147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBB() const { 915e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 91657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 9177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 9187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 9197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 9207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBH() const { 921e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 92257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 92357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0 ) 9247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 9257f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 9267f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 9277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 92857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0) 929ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 930ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 931ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 932ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach bool isT2MemRegOffset() const { 93357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 93457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0) 935ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 936ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach // Only lsl #{0, 1, 2, 3} allowed. 937e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType == ARM_AM::no_shift) 938ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 939e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 940ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 941ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 942ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 9447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 9457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 946e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 94757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 94887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 949e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach return isARMLowRegister(Memory.BaseRegNum) && 950e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 95160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 95260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 953e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 95457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 95560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 95660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 957e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 958e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 959ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 960ecd858968384be029574d845eb098d357049e02eJim Grosbach } 96138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 962e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 96357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 96438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 96538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 966e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 967e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 96838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 96938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 97048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 971e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 97257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 97348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 97448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 975e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 976e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 97748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 97848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 979ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 98057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 98157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 982ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 983ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 984e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 985e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 986ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 987505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 988a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isMemImm8s4Offset() const { 98957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 990a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 991a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate offset a multiple of 4 in range [-1020, 1020]. 992e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 993e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 995a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 996b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach bool isMemImm0_1020s4Offset() const { 99757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 998b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return false; 999b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // Immediate offset a multiple of 4 in range [0, 1020]. 1000e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1001e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 1003b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 10047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 100557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1006f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 10077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 1008e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1009e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 10104d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson return (Val == INT32_MIN) || (Val > -256 && Val < 256); 1011f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1012f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach bool isMemPosImm8Offset() const { 101357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1014f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return false; 1015f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach // Immediate offset in range [0, 255]. 1016e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1017e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1018f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return Val >= 0 && Val < 256; 1019f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1020a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemNegImm8Offset() const { 102157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1022a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 1023a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [-255, -1]. 1024df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach if (!Memory.OffsetImm) return false; 1025e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1026df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach return (Val == INT32_MIN) || (Val > -256 && Val < 0); 1027a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1028a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemUImm12Offset() const { 102957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1030a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 1031a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [0, 4095]. 1032e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1033e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 1034a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return (Val >= 0 && Val < 4096); 1035a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 10367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 103709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 103809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 103909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 104021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 104109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 104209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 104357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1044ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 10457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 1046e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 1047e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 10480da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 10497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 10507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 105121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 10527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 10537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1054ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 10557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 105663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 1057ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 10582bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isPostIdxImm8s4() const { 10592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Kind != k_Immediate) 10602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return false; 10612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (!CE) return false; 10632bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int64_t Val = CE->getValue(); 10642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 10652bd0118472de352745a2e038245fab4974f7c87eJim Grosbach (Val == INT32_MIN); 10662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 10677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 106821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMSRMask() const { return Kind == k_MSRMask; } 106921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isProcIFlags() const { return Kind == k_ProcIFlags; } 10703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 10710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // NEON operands. 1072862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach bool isVecListOneD() const { 1073862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Kind != k_VectorList) return false; 1074862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return VectorList.Count == 1; 1075862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1076862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1077280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach bool isVecListTwoD() const { 1078280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach if (Kind != k_VectorList) return false; 1079280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach return VectorList.Count == 2; 1080280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach } 1081280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach 1082cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach bool isVecListThreeD() const { 1083cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach if (Kind != k_VectorList) return false; 1084cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach return VectorList.Count == 3; 1085cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach } 1086cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach 1087b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach bool isVecListFourD() const { 1088b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach if (Kind != k_VectorList) return false; 1089b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach return VectorList.Count == 4; 1090b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach } 1091b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach 10924661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach bool isVecListTwoQ() const { 10934661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach if (Kind != k_VectorList) return false; 10944661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach //FIXME: We haven't taught the parser to handle by-two register lists 10954661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach // yet, so don't pretend to know one. 10964661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach return VectorList.Count == 2 && false; 10974661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach } 10984661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach 109998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach bool isVecListOneDAllLanes() const { 110098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Kind != k_VectorListAllLanes) return false; 110198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return VectorList.Count == 1; 110298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 110398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 110413af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach bool isVecListTwoDAllLanes() const { 110513af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach if (Kind != k_VectorListAllLanes) return false; 110613af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach return VectorList.Count == 2; 110713af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach } 110813af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach 11097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach bool isVecListOneDByteIndexed() const { 11107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (Kind != k_VectorListIndexed) return false; 11117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return VectorList.Count == 1 && VectorList.LaneIndex <= 7; 11127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 11137636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 1114460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex8() const { 1115460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1116460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 8; 1117460a90540b045c102012da2492999557e6840526Jim Grosbach } 1118460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex16() const { 1119460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1120460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 4; 1121460a90540b045c102012da2492999557e6840526Jim Grosbach } 1122460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex32() const { 1123460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 1124460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 2; 1125460a90540b045c102012da2492999557e6840526Jim Grosbach } 1126460a90540b045c102012da2492999557e6840526Jim Grosbach 11270e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach bool isNEONi8splat() const { 11280e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (Kind != k_Immediate) 11290e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return false; 11300e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11310e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Must be a constant. 11320e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!CE) return false; 11330e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach int64_t Value = CE->getValue(); 11340e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // i8 value splatted across 8 bytes. The immediate is just the 8 byte 11350e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // value. 11360e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return Value >= 0 && Value < 256; 11370e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 1138460a90540b045c102012da2492999557e6840526Jim Grosbach 1139ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach bool isNEONi16splat() const { 1140ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Kind != k_Immediate) 1141ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return false; 1142ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1143ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // Must be a constant. 1144ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (!CE) return false; 1145ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach int64_t Value = CE->getValue(); 1146ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // i16 value in the range [0,255] or [0x0100, 0xff00] 1147ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00); 1148ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1149ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 11506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32splat() const { 11516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 11526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 11536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 11556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 11566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 11576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X. 11586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 11596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 11606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 11616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000); 11626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 11636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 11646248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32vmov() const { 11656248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 11666248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 11676248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11686248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 11696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 11706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 11716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 11726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 11736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 11746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 11756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 11766248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000) || 11776248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 11786248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 11796248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 11806248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1181f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach bool isNEONi64splat() const { 1182f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (Kind != k_Immediate) 1183f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return false; 1184f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1185f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // Must be a constant. 1186f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (!CE) return false; 1187f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1188f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // i64 value with each byte being either 0 or 0xff. 1189f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i) 1190f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 1191f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return true; 1192f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1193f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 11943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 119514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 119614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 119714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 119814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 11993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 12003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 12013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 12023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 12033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1205345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 12068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 120704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 120804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 12098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 12108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1211fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 1212fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1213fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 1214fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1215fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 12169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 12179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 12189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(getCoproc())); 12199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 12209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 12219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 12229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 12239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val)); 12249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 12259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 122689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 122789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 122889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 122989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 123089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 123189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 123289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 123389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 123489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 123589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 1236d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 1237d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1238d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 1239d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1240d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 1241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 1242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 1243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 1244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1246af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 1247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1248430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach assert(isRegShiftedReg() && 1249430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach "addRegShiftedRegOperands() on non RegShiftedReg!"); 1250af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 1251af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 1252e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 1253af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 1254e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1255e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1256af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 1257152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 1258430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach assert(isRegShiftedImm() && 1259430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach "addRegShiftedImmOperands() on non RegShiftedImm!"); 1260af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 126192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 1262af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 126392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 126492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1265580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 12660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 1267580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 1268580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 12690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 12700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 127187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 12727729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 12735fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 12745fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 12757729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 12767729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 127787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 127887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 12790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 12800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 12810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 12820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 12830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 12840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 12850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 12860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 12877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 12887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 12897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 12907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 12917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 12927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1294293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1295293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 1296293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 1297293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 1298293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1299293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1300293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 1301293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 1302293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1303293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 13043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 13056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 13076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 13086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 13099d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 13109d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13119d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 13129d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 13139d39036f62674606565217a10db28171b9594bc7Jim Grosbach 1314a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1315a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1316a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 1317a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 1318a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1319a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1320a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1321a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 132272f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 132372f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 132472f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 132572f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 132672f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 132772f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 132872f39f8436848885176943b0ba985a7171145423Jim Grosbach } 132972f39f8436848885176943b0ba985a7171145423Jim Grosbach 133072f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 133172f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 133272f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 133372f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 133472f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 133572f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 133672f39f8436848885176943b0ba985a7171145423Jim Grosbach } 133772f39f8436848885176943b0ba985a7171145423Jim Grosbach 1338f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1339f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1340f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1341f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1342f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1343f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1344f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1345f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 13464a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 13474a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 13484a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 13494a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 13504a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 13514a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 13524a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 13534a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 135470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 135570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 135670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 135770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 135870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 135970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 136070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1361ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1362ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1366f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1367f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1371f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 137289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const { 137389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 137489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach // The operand is actually a t2_so_imm, but we have its bitwise 137589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach // negation in the assembly source, so twiddle it here. 137689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 137789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 137889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach } 137989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach 13803bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const { 13813bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 13823bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // The operand is actually a t2_so_imm, but we have its 13833bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // negation in the assembly source, so twiddle it here. 13843bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 13853bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 13863bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 13873bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach 1388e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const { 1389e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1390e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach // The operand is actually a so_imm, but we have its bitwise 1391e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach // negation in the assembly source, so twiddle it here. 1392e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1393e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 1394e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach } 1395e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach 13963bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const { 13973bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 13983bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // The operand is actually a so_imm, but we have its 13993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach // negation in the assembly source, so twiddle it here. 14003bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 14023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach } 14033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach 1404706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1405706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1406706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1407706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1408706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 14097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 14107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1411e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1412505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1413505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 141457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 141557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 141657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 141757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 141857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 141957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 14207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 14217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1422e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1423e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 14247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 14257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 14267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 14277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 14287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 14297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 14307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 14317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 1432e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1433e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1434ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1435e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1436e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1438ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1439ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1440039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1441039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1442039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1443039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1444039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1445039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1446039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1447039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1448039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1449039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1450039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1451039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1452039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1453039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 14542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 14552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1456e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1457e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 14582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 14592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 14602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 14612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 14622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 14632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 14642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 14652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 1466e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 14672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 1468e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1469e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 14722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 14732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 14742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 147521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) { 14762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 14772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 14782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 14792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1480251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 14812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 14822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 14832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 14842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 14852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 14862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 14872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 14882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 14892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1490251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 14912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 14922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 14942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 14957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 14967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1497681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // If we have an immediate that's not a constant, treat it as a label 1498681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // reference needing a fixup. If it is a constant, it's something else 1499681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // and we reject it. 1500681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach if (isImm()) { 1501681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Inst.addOperand(MCOperand::CreateExpr(getImm())); 1502681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1503681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach return; 1504681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach } 1505681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach 15067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1507e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 15087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 15097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 15107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 15117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 15127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 1513e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 15147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 15157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 15167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1517a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1518a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1519e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1520e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1521a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1522a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1523a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1524b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1525b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1526b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1527e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1528e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1529b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1530b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1531b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 15327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 15337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1534e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1535e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 15367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1537ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1538ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1539f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1540f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1541f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1542f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1543a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1544f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1545a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1546a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1547a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1548a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1549a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 155021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 1551a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1552a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1553a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1554a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1555a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1556a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1557e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1558e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1559a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1560a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1561a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 15627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 15637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 156409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 156521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 156609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 156709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 156809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 156909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 157009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 157109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1572e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1573e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 15747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 15757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 157692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 15777f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 15787f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1579e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1580e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 15817f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 15827f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 15837f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 15847f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1585e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1586e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 15877f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 15887f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 15897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 15907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1591430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach unsigned Val = 1592430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1593430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach Memory.ShiftImm, Memory.ShiftType); 1594e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1595e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 15967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 15977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1598d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1599ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1600ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1601e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1602e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1603e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 1604ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1605ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 16067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 16077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1608e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1609e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 161014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 16113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 161260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 161360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1614e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1615e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 161660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 161748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 161848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 161938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 162038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1621e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 1622e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 162338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 162438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 162538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 162648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 162748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1628e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 1629e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 163048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 163160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 163260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1633ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1634ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1635e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1636e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1637ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1638ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1639ecd858968384be029574d845eb098d357049e02eJim Grosbach 16407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 16417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 16427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 16437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 16447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 16457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 164663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 16477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 16487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1649f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1650ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 16512bd0118472de352745a2e038245fab4974f7c87eJim Grosbach void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 16522bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 16532bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 16542bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(CE && "non-constant post-idx-imm8s4 operand!"); 16552bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int Imm = CE->getValue(); 16562bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isAdd = Imm >= 0; 16572bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Imm == INT32_MIN) Imm = 0; 16582bd0118472de352745a2e038245fab4974f7c87eJim Grosbach // Immediate is scaled by 4. 16592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 16602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 16612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 16622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach 16637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 16647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 16657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1666f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1667f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1668f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1669f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1670f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1671f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1672f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1673f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1674f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1675f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1676f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1677f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1678ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1679ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1680584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1681584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1682584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1683584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1684584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1685a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1686a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1687a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1688a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1689a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 16906029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach void addVecListOperands(MCInst &Inst, unsigned N) const { 1691862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1692862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1693862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1694862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 16957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach void addVecListIndexedOperands(MCInst &Inst, unsigned N) const { 16967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 16977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 16987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex)); 16997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 17007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 1701460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1702460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1703460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1704460a90540b045c102012da2492999557e6840526Jim Grosbach } 1705460a90540b045c102012da2492999557e6840526Jim Grosbach 1706460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1707460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1708460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1709460a90540b045c102012da2492999557e6840526Jim Grosbach } 1710460a90540b045c102012da2492999557e6840526Jim Grosbach 1711460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1712460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1713460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1714460a90540b045c102012da2492999557e6840526Jim Grosbach } 1715460a90540b045c102012da2492999557e6840526Jim Grosbach 17160e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 17170e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 17180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // The immediate encodes the type of constant as well as the value. 17190e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Mask in that this is an i8 splat. 17200e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 17210e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00)); 17220e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 17230e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 1724ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 1725ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1726ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // The immediate encodes the type of constant as well as the value. 1727ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1728ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach unsigned Value = CE->getValue(); 1729ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Value >= 256) 1730ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value = (Value >> 8) | 0xa00; 1731ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach else 1732ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value |= 0x800; 1733ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 1734ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1735ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 17366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 17376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 17386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 17396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 17406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 17416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xff00) 17426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | 0x200; 17436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xff0000) 17446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | 0x400; 17456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 17466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 17476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 17486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 17496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 17506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 17516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 17526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 17536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 17546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 17556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xffff) 17566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 17576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xffffff) 17586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 17596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 17606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 17616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 17626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 17636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1764f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 1765f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1766f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // The immediate encodes the type of constant as well as the value. 1767f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1768f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1769f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach unsigned Imm = 0; 1770f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 1771f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Imm |= (Value & 1) << i; 1772f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1773f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00)); 1774f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1775f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 1776b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1777b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 177889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 177921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ITCondMask); 178089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 178189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 178289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 178389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 178489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 178589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 17863a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 178721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CondCode); 1788345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1789345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1790345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 17913a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1792345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1793345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1794fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 179521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocNum); 1796fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1797fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1798fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1799fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1800fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1801fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1802fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 180321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocReg); 1804fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1805fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1806fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1807fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1808fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1809fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 18109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) { 18119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocOption); 18129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->Cop.Val = Val; 18139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->StartLoc = S; 18149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->EndLoc = E; 18159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return Op; 18169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 18179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 1818d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 181921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CCOut); 1820d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1821d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1822d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1823d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1824d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1825d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 18263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 182721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Token); 1828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1829762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1830762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1831762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 18323a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1833a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1834a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 183550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 183621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Register); 1837762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1838762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1839762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 18403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1841a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1842a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1843e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1844e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1845e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1846e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1847e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 184821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1849af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1850af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1851af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1852af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1853e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1854e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1855e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1856e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1857e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 185892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 185992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 186092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 186192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 186221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1863af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1864af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1865af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 186692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 186792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 186892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 186992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 187092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1871580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 18720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 187321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1874580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1875580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 18760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 18770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 18780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 18790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 18800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 18817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 188221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_RotateImmediate); 18837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 18847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 18857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 18867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 18877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 18887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1889293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1890293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 189121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 1892293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1893293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1894293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1895293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1896293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1897293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1898293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 18997729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 19005fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1901cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 190221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach KindTy Kind = k_RegisterList; 19030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1904d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 190521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_DPRRegisterList; 1906d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1907275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 190821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_SPRRegisterList; 19090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 19100f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 19115fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 19127729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 191324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1914cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1915cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1916cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 19178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 19188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 19198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 1920862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count, 1921862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc S, SMLoc E) { 1922862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorList); 1923862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.RegNum = RegNum; 1924862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.Count = Count; 1925862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->StartLoc = S; 1926862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->EndLoc = E; 1927862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return Op; 1928862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1929862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 193098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count, 193198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc S, SMLoc E) { 193298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorListAllLanes); 193398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->VectorList.RegNum = RegNum; 193498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->VectorList.Count = Count; 193598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->StartLoc = S; 193698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Op->EndLoc = E; 193798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Op; 193898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 193998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 19407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count, 19417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned Index, SMLoc S, SMLoc E) { 19427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorListIndexed); 19437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.RegNum = RegNum; 19447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.Count = Count; 19457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->VectorList.LaneIndex = Index; 19467636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->StartLoc = S; 19477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Op->EndLoc = E; 19487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return Op; 19497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 19507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 1951460a90540b045c102012da2492999557e6840526Jim Grosbach static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 1952460a90540b045c102012da2492999557e6840526Jim Grosbach MCContext &Ctx) { 1953460a90540b045c102012da2492999557e6840526Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorIndex); 1954460a90540b045c102012da2492999557e6840526Jim Grosbach Op->VectorIndex.Val = Idx; 1955460a90540b045c102012da2492999557e6840526Jim Grosbach Op->StartLoc = S; 1956460a90540b045c102012da2492999557e6840526Jim Grosbach Op->EndLoc = E; 1957460a90540b045c102012da2492999557e6840526Jim Grosbach return Op; 1958460a90540b045c102012da2492999557e6840526Jim Grosbach } 1959460a90540b045c102012da2492999557e6840526Jim Grosbach 19603a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 196121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Immediate); 1962762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1963762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1964762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 19653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1966cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1967cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 19689d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 196921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_FPImmediate); 19709d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 19719d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 19729d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 19739d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 19749d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 19759d39036f62674606565217a10db28171b9594bc7Jim Grosbach 19767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 19777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 19787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 19797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 19800d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 198157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment, 19827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 19833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 198421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Memory); 1985e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.BaseRegNum = BaseRegNum; 1986e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetImm = OffsetImm; 1987e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetRegNum = OffsetRegNum; 1988e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftType = ShiftType; 1989e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftImm = ShiftImm; 199057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Op->Memory.Alignment = Alignment; 1991e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.isNegative = isNegative; 19927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 19937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 19947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 19957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 199616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1997f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1998f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1999f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 20007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 200121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 20027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 2003f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 2004f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 2005f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 2006762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 2007762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 20083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 2009a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2010706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2011706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 201221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 2013706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 2014706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 2015706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 2016706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 2017706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 2018a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2019a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 202021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ProcIFlags); 2021a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 2022a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 2023a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 2024a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 2025a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2026584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2027584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 202821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MSRMask); 2029584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 2030584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 2031584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 2032584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 2033584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2034a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 2035a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2036a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 2037a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2038b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 2039fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 204021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 20419d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 20429d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 20439d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 204421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 20456a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 2046fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 204721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 2048d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 2049d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 205021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: { 20511a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer static const char *MaskStr[] = { 20521a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)", 20531a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)" 20541a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer }; 205589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 205689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 205789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 205889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 205921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 2060fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 2061fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 206221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 2063fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 2064fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 20659b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 20669b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OS << "<coprocessor option: " << CoprocOption.Val << ">"; 20679b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 206821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 2069584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 2070584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 207121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 2072fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 2073fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 207421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 2075706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 2076706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 207721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 20786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 2079e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach << " base:" << Memory.BaseRegNum; 20806ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 2081fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 208221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 2083f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 2084f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 2085f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 2086f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 2087f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 2088f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 20897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 209021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: { 2091a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 2092a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 2093a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 2094a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 2095a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 2096a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 2097a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 2098a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 209921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 210050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 2101fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 210221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 2103580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 2104580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 2105e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 210621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 210792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 2108efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << RegShiftedReg.SrcReg << " " 2109efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) 2110efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << " " << RegShiftedReg.ShiftReg << ">"; 21110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 211221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 211392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 2114efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << RegShiftedImm.SrcReg << " " 2115efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) 2116efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach << " #" << RegShiftedImm.ShiftImm << ">"; 211792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 211821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 21197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 21207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 212121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 2122293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 2123293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 2124293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 212521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 212621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 212721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: { 21288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 21298d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 21305fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 21315fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 21327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 21337729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 21347729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 21358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 21368d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 21378d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 21388d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 21398d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 2140862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 2141862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OS << "<vector_list " << VectorList.Count << " * " 2142862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach << VectorList.RegNum << ">"; 2143862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 214498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case k_VectorListAllLanes: 214598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach OS << "<vector_list(all lanes) " << VectorList.Count << " * " 214698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach << VectorList.RegNum << ">"; 214798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 21487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case k_VectorListIndexed: 21497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OS << "<vector_list(lane " << VectorList.LaneIndex << ") " 21507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach << VectorList.Count << " * " << VectorList.RegNum << ">"; 21517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 215221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 2153fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 2154fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 2155460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 2156460a90540b045c102012da2492999557e6840526Jim Grosbach OS << "<vectorindex " << getVectorIndex() << ">"; 2157460a90540b045c102012da2492999557e6840526Jim Grosbach break; 2158fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 2159fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 21603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 21613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 21623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 21633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 21643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 21653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 21663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 21673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 216869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 216969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 21701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 2171bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 2172bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 2173bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 2174bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 21759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 2176e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 2177e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 21783a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 21791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 218018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 21817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 2182d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 2183590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string lowerCase = Tok.getString().lower(); 21840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 21850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 21860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 21870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 21880c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 21890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 21900c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 219140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach // Additional register name aliases for 'gas' compatibility. 219240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a1", ARM::R0) 219340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a2", ARM::R1) 219440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a3", ARM::R2) 219540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("a4", ARM::R3) 219640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v1", ARM::R4) 219740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v2", ARM::R5) 219840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v3", ARM::R6) 219940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v4", ARM::R7) 220040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v5", ARM::R8) 220140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v6", ARM::R9) 220240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v7", ARM::R10) 220340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("v8", ARM::R11) 220440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("sb", ARM::R9) 220540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("sl", ARM::R10) 220640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach .Case("fp", ARM::R11) 22070c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 22080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 22090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 221069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 2211b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 2212460a90540b045c102012da2492999557e6840526Jim Grosbach 2213e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 2214e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 2215d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 221619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 221719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 221819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 221919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 222019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 22210d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 22220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 22240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 22250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 22260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2227590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string lowerCase = Tok.getString().lower(); 22280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 2229af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach .Case("asl", ARM_AM::lsl) 22300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 22310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 22320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 22330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 22340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 22350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 22360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 22370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 223819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 22390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 2241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 2242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 2243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 2244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 2245eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 2246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 2247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 2248e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 2249e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 2250e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 2251e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 2252e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 2253e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 2254e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 2255e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 2256e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 2257e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 22588a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 22598a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar)) { 2260e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 2261e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 2262e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 226319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 226419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 226519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 226619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2267e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 2268e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 226919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 227019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 227119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 227219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2273e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 2274e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 2275e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 2276e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 2277e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 2278e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 2279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 228019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 228119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 2282e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2283e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 22841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 2285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 228619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 228719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 228819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 228919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 229019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 229119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 2292e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 229319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 229419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2295e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2296e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 229792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 229892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 2299af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 23000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 230192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 230292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 230392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 23040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 230519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 23060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 23070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 23080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 230950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 231050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 231150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 2312e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 2313e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 2314e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 231550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 23161355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2317e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 23181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 2319e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 232050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2321d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 232250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 2323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2324e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 2325e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 232650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 232750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 2328e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 2329460a90540b045c102012da2492999557e6840526Jim Grosbach return false; 2330460a90540b045c102012da2492999557e6840526Jim Grosbach } 2331460a90540b045c102012da2492999557e6840526Jim Grosbach 2332460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 2333460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 2334460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 2335460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 2336460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 2337460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 2338460a90540b045c102012da2492999557e6840526Jim Grosbach 2339460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 2340460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 2341460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2342460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2343460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 2344460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 2345460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2346460a90540b045c102012da2492999557e6840526Jim Grosbach } 2347460a90540b045c102012da2492999557e6840526Jim Grosbach 2348460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2349460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 2350460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 2351460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2352460a90540b045c102012da2492999557e6840526Jim Grosbach } 2353460a90540b045c102012da2492999557e6840526Jim Grosbach 2354460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 2355460a90540b045c102012da2492999557e6840526Jim Grosbach 2356460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 2357460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 2358460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 235999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 236099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 236150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2362a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2363a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2364fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 2365fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 2366fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 2367fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 2368e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 2369e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 2370e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 2371e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 2372e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 2373fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 2374e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2375e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 2376e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2377e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 2378e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 2379e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 2380e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 2381e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 2382e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 2383e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 2384e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 2385e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 2386e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 2387e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2388e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2389e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 2390fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 2391e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2392e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 2393e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2394e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 2395e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 2396e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 2397e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 2398e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 2399e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 2400e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2401e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2402e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2403e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2404e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2405e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2406e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 240789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 240889df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 240989df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 241089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 241189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 241289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 241389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 241489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 241589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 241689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 241789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 241889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 241989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 242089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 242189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 242289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 242389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 242489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 242589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 242689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 242789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 242889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 242989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 243089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 243189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 243289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 243389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 243489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 243589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 243689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 243789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 243889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 243989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 244089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 244189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 244243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2443fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2444fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2445f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 244643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2447e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 2448e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 2449c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2450c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2451e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2452fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2453e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 2454f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2455e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2456e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 2457fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2458f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2459fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 2460fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 246143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2462fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2463fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2464f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 246543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2466fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2467fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2468c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2469c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2470fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2471fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2472fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 2473f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2474fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2475fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2476fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2477f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2478e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2479e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 24809b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 24819b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}' 24829b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 24839b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 24849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc S = Parser.getTok().getLoc(); 24859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 24869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // If this isn't a '{', this isn't a coprocessor immediate operand. 24879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 24889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_NoMatch; 24899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '{' 24909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 24919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCExpr *Expr; 24929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 24939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (getParser().ParseExpression(Expr)) { 24949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "illegal expression"); 24959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 24969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 24979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 24989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 24999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 25009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 25019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 25029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach int Val = CE->getValue(); 25039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 25049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // Check for and consume the closing '}' 25059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 25069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 25079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc E = Parser.getTok().getLoc(); 25089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '}' 25099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 25109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 25119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_Success; 25129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach} 25139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 2514d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 2515d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 2516d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 2517d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 2518d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 2519d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 2520d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 2521d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2522d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 2523d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 2524d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 2525d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2526d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2527d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2528d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2529d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2530d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2531d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2532d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2533d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2534d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 2535d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2536ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register. 2537ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) { 2538ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach switch (QReg) { 2539ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach default: llvm_unreachable("expected a Q register!"); 2540ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q0: return ARM::D0; 2541ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q1: return ARM::D2; 2542ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q2: return ARM::D4; 2543ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q3: return ARM::D6; 2544ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q4: return ARM::D8; 2545ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q5: return ARM::D10; 2546ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q6: return ARM::D12; 2547ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q7: return ARM::D14; 2548ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q8: return ARM::D16; 254925e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach case ARM::Q9: return ARM::D18; 2550ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q10: return ARM::D20; 2551ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q11: return ARM::D22; 2552ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q12: return ARM::D24; 2553ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q13: return ARM::D26; 2554ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q14: return ARM::D28; 2555ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q15: return ARM::D30; 2556ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 2557ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach} 2558ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach 2559d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 256050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 25611355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 256218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 2563a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 2564e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 2565d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 2566d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 256716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2568d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 2569d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 2570d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 2571d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 2572d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 2573d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2574ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 2575ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // space for that many. 2576ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2577ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach 2578ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2579ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2580ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Reg = getDRegFromQReg(Reg); 2581ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2582ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach ++Reg; 2583ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 25841a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCRegisterClass *RC; 2585d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2586d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2587d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2588d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2589d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2590d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2591d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 2592d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2593e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 2594ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Store the register. 2595d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2596d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2597d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 2598d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 2599d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 2600d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2601d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2602d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2603e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.Lex(); // Eat the minus. 2604d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2605d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 2606d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2607d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2608ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2609ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 2610ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach EndReg = getDRegFromQReg(EndReg) + 1; 2611d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2612d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2613d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2614d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2615d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2616d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2617d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2618d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2619d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2620d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2621d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2622d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2623d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2624d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2625d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2626d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2627d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2628d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2629d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2630d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2631d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2632a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach const AsmToken RegTok = Parser.getTok(); 2633d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2634d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 26352d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2636ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2637ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach bool isQReg = false; 2638ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2639ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Reg = getDRegFromQReg(Reg); 2640ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach isQReg = true; 2641ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 2642d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2643d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2644d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2645d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2646a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg)) 2647d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2648a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) { 2649a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach Warning(RegLoc, "duplicated register (" + RegTok.getString() + 2650a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach ") in register list"); 2651a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach continue; 2652a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach } 2653d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2654d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2655d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2656d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2657d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2658d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2659d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2660ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (isQReg) 2661ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc)); 2662d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2663d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2664d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2665d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2666d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2667d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2668e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 266950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 267050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2671d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2672d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 267398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists. 267498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 26757636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) { 26767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Index = 0; // Always return a defined index value. 267798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 267898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Parser.Lex(); // Eat the '['. 267998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Parser.getTok().is(AsmToken::RBrac)) { 268098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // "Dn[]" is the 'all lanes' syntax. 268198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach LaneKind = AllLanes; 268298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Parser.Lex(); // Eat the ']'. 268398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_Success; 268498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 26857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (Parser.getTok().is(AsmToken::Integer)) { 26867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach int64_t Val = Parser.getTok().getIntVal(); 26877636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // Make this range check context sensitive for .8, .16, .32. 26887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (Val < 0 && Val > 7) 26897636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Error(Parser.getTok().getLoc(), "lane index out of range"); 26907636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Index = Val; 26917636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach LaneKind = IndexedLane; 26927636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Parser.Lex(); // Eat the token; 26937636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 26947636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Error(Parser.getTok().getLoc(), "']' expected"); 26957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Parser.Lex(); // Eat the ']'. 26967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return MatchOperand_Success; 26977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 26987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Error(Parser.getTok().getLoc(), "lane index must be empty or an integer"); 269998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 270098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 270198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach LaneKind = NoLanes; 270298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_Success; 270398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach} 270498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach 2705862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list 2706862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2707862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 270898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy LaneKind; 27097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned LaneIndex; 27105c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach SMLoc S = Parser.getTok().getLoc(); 27115c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // As an extension (to match gas), support a plain D register or Q register 27125c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // (without encosing curly braces) as a single or double entry list, 27135c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // respectively. 27145c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) { 27155c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach int Reg = tryParseRegister(); 27165c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Reg == -1) 27175c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_NoMatch; 27185c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 27195c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) { 27207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex); 272198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Res != MatchOperand_Success) 272298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Res; 272398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 272498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 272598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind!"); 272698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 272798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 272898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, S, E)); 272998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 273098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 273198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 273298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, S, E)); 273398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 27347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 27357636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1, 27367636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach LaneIndex, S,E)); 27377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 273898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 27395c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_Success; 27405c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 27415c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 27425c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Reg = getDRegFromQReg(Reg); 27437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex); 274498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach if (Res != MatchOperand_Success) 274598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return Res; 274698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 274798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 274898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind!"); 274998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 275098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 275198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, S, E)); 275298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 275398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 275498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach E = Parser.getTok().getLoc(); 275598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, S, E)); 275698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 27577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 27587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2, 27597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach LaneIndex, S,E)); 27607636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 276198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 27625c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_Success; 27635c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 27645c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Error(S, "vector register expected"); 27655c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_ParseFail; 27665c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 27675c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach 27685c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 2769862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_NoMatch; 2770862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2771862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '{' token. 2772862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 2773862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2774862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int Reg = tryParseRegister(); 2775862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2776862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2777862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2778862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2779862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count = 1; 2780c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach unsigned FirstReg = Reg; 2781c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // The list is of D registers, but we also allow Q regs and just interpret 2782c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // them as the two D sub-registers. 2783c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2784c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach FirstReg = Reg = getDRegFromQReg(Reg); 2785c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Reg; 2786c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Count; 2787c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 27887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success) 278998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 2790c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach 2791e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2792e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2793e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2794e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Parser.Lex(); // Eat the minus. 2795e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2796e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach int EndReg = tryParseRegister(); 2797e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (EndReg == -1) { 2798e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "register expected"); 2799e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2800e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 2801e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2802e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 2803e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach EndReg = getDRegFromQReg(EndReg) + 1; 2804e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // If the register is the same as the start reg, there's nothing 2805e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // more to do. 2806e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Reg == EndReg) 2807e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach continue; 2808e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // The register must be in the same register class as the first. 2809e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) { 2810e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "invalid register in register list"); 2811e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2812e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 2813e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Ranges must go from low to high. 2814e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach if (Reg > EndReg) { 2815e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Error(EndLoc, "bad range in register list"); 2816e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach return MatchOperand_ParseFail; 2817e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 281898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 281998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 28207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 28217636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 282298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 28237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 282498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 282598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 282698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 282798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach EndLoc = Parser.getTok().getLoc(); 2828e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach 2829e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach // Add all the registers in the range to the register list. 2830e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Count += EndReg - Reg; 2831e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach Reg = EndReg; 2832e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach continue; 2833e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach } 2834862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat the comma. 2835862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach RegLoc = Parser.getTok().getLoc(); 2836862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int OldReg = Reg; 2837862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Reg = tryParseRegister(); 2838862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2839862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2840862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2841862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2842c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // vector register lists must be contiguous. 2843862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // It's OK to use the enumeration values directly here rather, as the 2844862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // VFP register classes have the enum sorted properly. 2845c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // 2846c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // The list is of D registers, but we also allow Q regs and just interpret 2847c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // them as the two D sub-registers. 2848c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2849c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Reg = getDRegFromQReg(Reg); 2850c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (Reg != OldReg + 1) { 2851c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Error(RegLoc, "non-contiguous register range"); 2852c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach return MatchOperand_ParseFail; 2853c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 2854c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Reg; 2855c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Count += 2; 285698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 285798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 28587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 285998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 28607636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 286198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 28627636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 286398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 286498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 286598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 2866c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach continue; 2867c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 2868c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // Normal D register. Just check that it's contiguous and keep going. 2869862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg != OldReg + 1) { 2870862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "non-contiguous register range"); 2871862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2872862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2873862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ++Count; 287498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach // Parse the lane specifier if present. 287598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach VectorLaneTy NextLaneKind; 28767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach unsigned NextLaneIndex; 287798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 28787636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success) 287998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 28807636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 288198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Error(EndLoc, "mismatched lane index in register list"); 288298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach return MatchOperand_ParseFail; 288398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 2884862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2885862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2886862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2887862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) { 2888862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(E, "'}' expected"); 2889862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2890862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2891862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '}' token. 2892862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 289398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach switch (LaneKind) { 289498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach default: 289598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach assert(0 && "unexpected lane kind in register list."); 289698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case NoLanes: 289798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E)); 289898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 289998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach case AllLanes: 290098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count, 290198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach S, E)); 290298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach break; 29037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach case IndexedLane: 29047636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count, 29057636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach LaneIndex, S, E)); 29067636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach break; 290798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach } 2908862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_Success; 2909862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach} 2910862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 291143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2912f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 291343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2914706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2915706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2916706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2917706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 2918706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2919706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2920706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 2921706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 2922032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 2923706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 2924032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 2925706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 2926706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 2927032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 2928706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 2929032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 2930706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 2931706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 2932706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 2933706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2934706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 2935f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2936706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2937706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2938706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2939f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2940706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 2941706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 294243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2943a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 294443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2945a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2946a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2947a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2948a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 2949a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 29502dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // An iflags string of "none" is interpreted to mean that none of the AIF 29512dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // bits are set. Not a terribly useful instruction, but a valid encoding. 2952a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 29532dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (IFlagsStr != "none") { 29542dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 29552dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 29562dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("a", ARM_PROC::A) 29572dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("i", ARM_PROC::I) 29582dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("f", ARM_PROC::F) 29592dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Default(~0U); 29602dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 29612dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // If some specific iflag is already set, it means that some letter is 29622dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // present more than once, this is not acceptable. 29632dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (Flag == ~0U || (IFlags & Flag)) 29642dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson return MatchOperand_NoMatch; 29652dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 29662dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson IFlags |= Flag; 29672dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson } 2968a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2969a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2970a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2971a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2972a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 2973584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 2974584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 297543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2976584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 297743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2978584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2979584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2980584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2981584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 2982584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2983acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 2984acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 2985acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2986acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 2987acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 2988acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 2989acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 2990acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 2991acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 2992acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 2993acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 2994acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 2995acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 2996acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 2997acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 2998acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 2999acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 3000acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 3001acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3002acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 3003acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 3004acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3005acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 3006acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 3007acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 3008acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3009acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 3010acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 3011acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 3012acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 3013acad68da50581de905a994ed3c6b9c197bcea687James Molloy 3014584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 3015584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 3016584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 3017590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string SpecReg = Mask.slice(Start, Next).lower(); 3018584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 3019584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 3020584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3021584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 3022584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 3023584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 3024584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 3025584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3026584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 3027584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 3028b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 3029584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 3030584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 3031584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 3032584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 30334b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 3034584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 3035584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3036584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 3037bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 30384b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 3039584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 304056926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 304156926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 3042584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 3043584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 3044584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 3045584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 3046584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 3047584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 3048584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 3049584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3050584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 3051584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 3052584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 3053584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3054584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 3055584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 3056584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 3057584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 3058584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 30597784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // Special register without flags is NOT equivalent to "fc" flags. 30607784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // NOTE: This is a divergence from gas' behavior. Uncommenting the following 30617784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // two lines would enable gas compatibility at the expense of breaking 30627784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // round-tripping. 30637784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // 30647784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // if (!FlagsVal) 30657784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // FlagsVal = 0x9; 3066584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3067584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 3068584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 3069584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 3070584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3071584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 3072584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 3073584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 3074a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 3075a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3076f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3077f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 3078f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 3079f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 3080f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3081f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 3082f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3083f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3084f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 3085590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string LowerOp = Op.lower(); 3086590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string UpperOp = Op.upper(); 3087f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 3088f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 3089f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3090f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3091f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 3092f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3093f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 30948a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 30958a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3096f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3097f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3098f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3099f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 3100f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3101f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 3102f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 3103f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 3104f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 3105f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3106f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3107f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 3108f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 3109f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 3110f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3111f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3112f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 3113f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 3114f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 3115f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 3116f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 3117f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3118f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 3119f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3120f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 3121f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 3122f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 3123c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3124c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3125c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 3126c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 3127c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3128c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 3129c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 3130c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 3131c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 3132c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 3133c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 3134c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 3135c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 3136c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 3137c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 3138c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 3139c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 3140c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 3141c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 3142c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 3143c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 3144c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 3145c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 3146c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 3147580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 3148580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 3149580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 3150580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 3151580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 3152580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3153580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3154580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 3155580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 3156580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 3157580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 3158580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3159580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3160580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 3161580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 3162580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 3163580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 3164580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 3165580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 3166580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 3167580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 3168580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3169580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3170580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 3171580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3172580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 31738a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 31748a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3175580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3176580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3177580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3178580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 3179580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3180580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 3181580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 3182580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 3183580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 3184580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3185580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3186580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 3187580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 3188580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 3189580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3190580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3191580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3192580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 3193580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 3194580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 3195580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 3196580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 3197580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3198580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 31990afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 32000afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 32010afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 32020afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 32030afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 3204580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 3205580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 3206580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 3207580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 3208580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 3209580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 3210580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3211580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 3212580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3213580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 3214580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 3215580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 3216580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 3217580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 3218580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 32197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 32207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 32217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 32227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 32237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 32257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 3226326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 3227326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 32287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 3229326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 3230326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 32317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 32327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 32348a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 32358a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 32367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 32377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 32387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 32397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 32407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 32427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 32437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 32447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 32457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 32467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 32477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 32487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 32497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 32507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 32517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 32527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 32547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 32557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 32567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 32577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 32587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 32597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 32607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 32617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 32637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 32647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 32657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 32667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 32677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 3268293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3269293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3270293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 3271293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 32728a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 32738a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3274293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3275293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3276293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3277293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 3278293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3279293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 3280293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3281293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 3282293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 3283293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3284293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3285293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 3286293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 3287293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 3288293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3289293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3290293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3291293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 3292293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 3293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 3294293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 3295293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3296293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3297293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 3298293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3299293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 3300293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 3301293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 3302293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3303293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3304293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 33058a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 33068a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) { 3307293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 3308293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3309293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3310293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 3311293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3312293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 3313293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 3314293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 3315293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3316293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3317293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 3318293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 3319293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 3320293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3321293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3322293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3323293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 3324293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 3325293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 3326293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 3327293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 3328293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 3329293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 3330293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3331293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 3332293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 3333293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 3334293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 3335293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 33367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 33377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 33387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 3339f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 3340f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 3341f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 33427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 33437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 33447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 33457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 33467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 33477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 33487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 334916578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 33507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 33517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 33527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 33537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 33547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 33557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 335616578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 33577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 33587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 33597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 33607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 33617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 33627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 33637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 33647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 33657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 33667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 33677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 33687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3369f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 3370f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 33710d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 33720d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 33730d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 33740d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 33750d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 3376f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 3377f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 3378f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 33797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 33807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 33817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 33827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3383251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3384251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3385251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 3386251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 3387251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 3388251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 3389251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 3390251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 3391251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 3392251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3393251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 3394251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 3395251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 3396251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 3397251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 3398251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3399251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 34008a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 34018a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar)) { 3402251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 3403251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 3404251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 3405251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 3406251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 3407251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 3408251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3409251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 3410251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 3411251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 3412251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3413251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3414251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 3415251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 3416251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 3417251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 3418251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 3419251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3420251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 3421251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 3422251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3423251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3424251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3425251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3426251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3427251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 3428251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 3429251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 3430251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 3431251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 3432251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 3433251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 3434251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 3435251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 3436251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 3437251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3438251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 3439251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 3440251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 3441251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 3442251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 3443251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 3444251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3445251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3446251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3447251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3448251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 3449251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 3450251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3451251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3452251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 3453251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3454a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 3455a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3456a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3457a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3458a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 3459a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3460a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3461a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3462a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3463a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3464a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3465a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3466a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3467a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3468a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3469a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3470a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3471a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3472a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 3473a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3474a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3475a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3476a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 3477a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3478a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3479a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3480a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3481a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3482a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3483a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3484a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3485a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3486a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3487a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3488a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3489a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3490eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3491eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3492eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3493eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 3494eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3495eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3496eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3497eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3498eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 3499eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3500eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3501eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3502eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3503eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 3504eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 3505eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3506ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3507ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3508ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3509ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 3510ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3511ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3512ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 3513ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3514ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3515ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3516ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3517ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 3518ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 3519ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 35201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3521ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3522ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3523ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 35241355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3525ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3526ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3527ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 3528ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3529ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3530ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 35317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3532ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3533ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3534ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3535ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 35369ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 35379ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 35389ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 35399ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 35409ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 35419ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 35429ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 35439ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 35449ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 35459ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 35469ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 35479ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 35489ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 35499ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 35509ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 35519ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 35529ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 3553548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 3554548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3555548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3556548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 3557548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 3558548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3559548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 3560548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3561548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3562548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 3563548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3564548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 3565548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 3566548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 35671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3568ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3569ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3570ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 35711355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3572ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3573ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3574ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3575548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3576548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3577548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 35787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 35797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 35807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 35817b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 35827b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 35837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 35847b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 35857b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 35867b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 35877b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 35887b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 35897b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 35907b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 35917b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 35927b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 35937b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 35947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 35957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 35967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 35977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 35987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 35997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 36007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 36017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3602ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 36037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 36047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 36057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 36067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 36077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 36087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 36097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3611ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3612ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 36147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 3615ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3616ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3617ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 36187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 36197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 36207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3621aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3622ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3623ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 36247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 36257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 36267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 36277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 36287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 36297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 36307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 36317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 3632aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 36337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 36347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 36357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 36367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 36377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 36387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 36397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 36407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 36417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 36427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 36437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 36447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 36457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 36467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 36477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3648ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3649ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3650ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3651ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 36527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 3653ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3654ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3655ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 36567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 36577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3658ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3659ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 36607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3661ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 36627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 36637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 36647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 36657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 36667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3667ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3668ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3670ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 36712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 36722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 36732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 36742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 36752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 36762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 36772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 36782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 36792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 36802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 36812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 36822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 36832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 36842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 36852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 36862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 36872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 36882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 368914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 369014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 369114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 369214605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 369314605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 369414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 369514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 369614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 369714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 369814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 369914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 370014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 370114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 370214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 370314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 370414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 370514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 370614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 3707623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 3708623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3709623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3710623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 3711623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 3712623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3713623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3714623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 3715623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3716623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 3717623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3718623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 3719623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 3720623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 372188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 372288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 372388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 372488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 372588ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 372688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 372788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 372888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 372988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 37307a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 37317a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 37327a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 37337a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 373488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 37357a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 373688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 373788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 373888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 373988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 37401b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach // If we have a three-operand form, make sure to set Rn to be the operand 37411b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach // that isn't the same as Rd. 37421b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach unsigned RegOp = 4; 37431b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach if (Operands.size() == 6 && 37441b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[4])->getReg() == 37451b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[3])->getReg()) 37461b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach RegOp = 5; 37471b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1); 37481b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach Inst.addOperand(Inst.getOperand(0)); 374988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 375088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 375188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 375288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 3753623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 375412431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser:: 375512431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode, 375612431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 375712431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vd 37586029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 375912431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Create a writeback register dummy placeholder. 376012431329d617064d6e72dd040a58c1635cc261abJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 376112431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vn 376212431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 376312431329d617064d6e72dd040a58c1635cc261abJim Grosbach // pred 376412431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 376512431329d617064d6e72dd040a58c1635cc261abJim Grosbach return true; 376612431329d617064d6e72dd040a58c1635cc261abJim Grosbach} 376712431329d617064d6e72dd040a58c1635cc261abJim Grosbach 376812431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser:: 376912431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode, 377012431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 377112431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vd 37726029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 377312431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Create a writeback register dummy placeholder. 377412431329d617064d6e72dd040a58c1635cc261abJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 377512431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vn 377612431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 377712431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vm 377812431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 377912431329d617064d6e72dd040a58c1635cc261abJim Grosbach // pred 378012431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 378112431329d617064d6e72dd040a58c1635cc261abJim Grosbach return true; 378212431329d617064d6e72dd040a58c1635cc261abJim Grosbach} 378312431329d617064d6e72dd040a58c1635cc261abJim Grosbach 37844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser:: 37854334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode, 37864334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 37874334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Create a writeback register dummy placeholder. 37884334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 37894334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vn 37904334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 37914334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vt 37926029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 37934334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // pred 37944334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 37954334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach return true; 37964334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach} 37974334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach 37984334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser:: 37994334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode, 38004334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 38014334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Create a writeback register dummy placeholder. 38024334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 38034334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vn 38044334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 38054334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vm 38064334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 38074334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vt 38086029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1); 38094334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // pred 38104334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 38114334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach return true; 38124334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach} 38134334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach 3814e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 38159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 381650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 38177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3818762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 381918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3820a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 3821762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3822b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 3823a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 382418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 38251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 38267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 38277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 3828a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 38290571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 38300571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 38310571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 38327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 38330571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 38347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 3835762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 3836b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 3837a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 38387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 383957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 0, 0, false, S, E)); 384003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 3841fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3842fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 3843fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3844fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3845fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 3846fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 3847fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 38487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 38497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 385050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 38517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 38527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 385350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 385457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a ':', it's an alignment specifier. 385557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Colon)) { 385657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the ':'. 385757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 385857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 385957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCExpr *Expr; 386057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (getParser().ParseExpression(Expr)) 386157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return true; 386257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 386357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // The expression has to be a constant. Memory references with relocations 386457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // don't come through here, as they use the <label> forms of the relevant 386557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // instructions. 386657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 386757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!CE) 386857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error (E, "constant expression expected"); 386957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 387057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Align = 0; 387157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach switch (CE->getValue()) { 387257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach default: 387357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "alignment specifier must be 64, 128, or 256 bits"); 387457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 64: Align = 8; break; 387557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 128: Align = 16; break; 387657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 256: Align = 32; break; 387757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 387857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 387957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Now we should have the closing ']' 388057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 388157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 388257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "']' expected"); 388357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat right bracket token. 388457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 388557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Don't worry about range checking the value here. That's handled by 388657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // the is*() predicates. 388757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 388857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, Align, 388957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 389057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 389157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 389257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // operand. 389357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 389457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 389557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the '!'. 389657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 389757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 389857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return false; 389957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 390057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 390157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a '#', it's an immediate offset, else assume it's a register 39026cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach // offset. Be friendly and also accept a plain integer (without a leading 39036cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach // hash) for gas compatibility. 39046cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 39058a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().is(AsmToken::Dollar) || 39066cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach Parser.getTok().is(AsmToken::Integer)) { 39078a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Integer)) 39086cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach Parser.Lex(); // Eat the '#'. 39097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 391050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 39110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 39127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 39137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 39147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 391505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 39167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 39177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 39187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 39197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 39207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 39217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 39227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 39230da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 39240da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 39250da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 39260da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 39270da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 39287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 39297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 39307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 39317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 39327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 393305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 39347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 39357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 39367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 393757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, 0, 393857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 3939a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 39407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 39417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 39427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 39437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 39447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 3945762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 39467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 39477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 39489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 3949d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 39507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 39517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 39527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 39537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 39547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 39557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 39567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 39577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 39587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 39599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 39607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 39617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 39627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 39637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 39647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 39657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 39667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 39670d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 39687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 39697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 39700d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 39717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 39729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 397316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 39747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 39757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 39767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 39777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 39787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 39797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 39807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 398157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ShiftType, ShiftImm, 0, isNegative, 39827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 39837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3984f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3985f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 3986f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3987f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3988f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 3989f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 39909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 39919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 39929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 39939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 39947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 3995a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 3996a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 39977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 39987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 39997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 40007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 400118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4002a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 4003a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 400438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 4005af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL" || 4006af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach ShiftName == "asl" || ShiftName == "ASL") 40070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 4008a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 40090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 4010a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 40110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 4012a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 40130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 4014a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 40150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 4016a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 40177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 4018b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 4019a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 40217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 40227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 40237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 40247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 40257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 40268a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (HashTok.isNot(AsmToken::Hash) && 40278a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach HashTok.isNot(AsmToken::Dollar)) 40287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 40297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 40309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 40317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 40327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 40337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 40347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 40357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 40367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 40377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 40387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 40397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 40407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 40417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 40427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 40437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 40447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 40457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 40467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 4047a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4048a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 4049a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 4050a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40519d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 40529d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 40539d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 40549d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 40559d39036f62674606565217a10db28171b9594bc7Jim Grosbach 40568a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash) && 40578a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach Parser.getTok().isNot(AsmToken::Dollar)) 40589d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 40590e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 40600e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Disambiguate the VMOV forms that can accept an FP immediate. 40610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <sreg>, #imm 40620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f64 <dreg>, #imm 40630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <dreg>, #imm @ vector f32x2 40640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <qreg>, #imm @ vector f32x4 40650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // 40660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // There are also the NEON VMOV instructions which expect an 40670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // integer constant. Make sure we don't try to parse an FPImm 40680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // for these: 40690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.i{8|16|32|64} <dreg|qreg>, #imm 40700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]); 40710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!TyOp->isToken() || (TyOp->getToken() != ".f32" && 40720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach TyOp->getToken() != ".f64")) 40730e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return MatchOperand_NoMatch; 40740e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 40759d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 40769d39036f62674606565217a10db28171b9594bc7Jim Grosbach 40779d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 40789d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 40799d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 40809d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 40819d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 40829d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 40839d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 40849d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 40859d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 40869d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 40879d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 40889d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 40899d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 40909d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 40919d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 40929d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 40939d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 40949d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 40959d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 40969d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 40979d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 40989d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 40999d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 41009d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 41019d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 41029d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 41039d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 41049d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 41059d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 41069d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 41079d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 41089d39036f62674606565217a10db28171b9594bc7Jim Grosbach 41099d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 41109d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 41119d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 41129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 41139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 41141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4115fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 4116762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 4117fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 4118fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 4119fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 4120f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 4121f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 4122fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 4123f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 4124f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 4125f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 4126f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 4127f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 4128fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 4129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 4130146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 4131146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 413250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 413319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 41345cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 41351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 413650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 41370d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 413819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 41390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 414019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 414119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 41425cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 41435cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 41445cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 41455cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 41465cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 41475cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 4148e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 4149e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 4150e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 415119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 4152758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach case AsmToken::LParen: // parenthesized expressions like (_strcmp-4) 415367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 41546284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach case AsmToken::String: // quoted label names. 415567b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 4156515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 4157515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 4158515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 4159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 4160515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 416150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 4162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 416350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 416450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 416550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 4166a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 41671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 4168d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 41691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 41708a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach case AsmToken::Dollar: 417163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 4172079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 4173079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 4174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 4175b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 417663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 4177515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 4178515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 417950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 418063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 4181ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach if (CE) { 4182ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach int32_t Val = CE->getValue(); 4183ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach if (isNegative && Val == 0) 4184ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 418563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 4186762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 418750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 418850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 418963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 41909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 41919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 41927597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 41937597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 41947597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 41951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 41969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 41979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 41987597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 41997597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 42009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42027597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 42037597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 42049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 42057597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 42069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 42079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 4208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 4210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 42111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 42127597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 42131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 42147597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 42159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 42178a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 42189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 42199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 42219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 42229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 42249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 42269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 42277597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 42289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 42297597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 42309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 42319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 42329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 42349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 42359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 42369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 42379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 42389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 42399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 42409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 42419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 42429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 42439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 4244352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 4245352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 4246352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 4247badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 424889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 42491355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 42505f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 42515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 425289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 425389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 4254352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 4255352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 4256a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 4257352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 4258badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 4259352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 4260352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 42615f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 42625f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 42635f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 42645f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 42655f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 42665f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 42675f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 42685f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 4269352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 4270badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 42713f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 42723f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 4273ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 427471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 427504d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 42762f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 42773f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 42783f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 42793f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 42803f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 42813f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 42823f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 42833f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 42843f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 42853f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 42863f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 42873f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 42883f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 42893f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 42903f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 42913f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 42923f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 42933f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 42943f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 42953f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 42963f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 42973f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 42983f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 42993f00e317064560ad11168d22030416d853829f6eJim Grosbach } 430052925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 4301345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4302352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 4303352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 4304352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 430500f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 43065f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 43075f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 43085f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 430967ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" || 431048171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" || 4311f10154010ec01a6965f86e8c136db79732c92eeeJim Grosbach Mnemonic == "fsts" || 4312e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 4313352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 4314352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 4315352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 4316352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 4317a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 4318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 4319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 4320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 4321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 4322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 4323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 4324a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 4325a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 4326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 4327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 4328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 4329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 433289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 433389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 433489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 433589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 433689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 433789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4338352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 4339352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 43403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 43413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 43423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 43433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 43443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 4345fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 43461355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 4347fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 4348eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 4349eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 43503443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 4351eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 4352d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 4353eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 4354d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 43553443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 4356d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 4357d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 4358eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 4359fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 4360eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 43613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 4362eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 4363eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 4364eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 4365eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 4366ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 4367ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 43680780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 43692bd0118472de352745a2e038245fab4974f7c87eJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" || 43702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "ldc2" || Mnemonic == "ldc2l" || 43712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) || 43724af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 43734af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 43741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 43753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 4376fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 43773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 4378fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 4379fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 4380fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 438163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 4382fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 4383fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 4384badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 4385badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 4386d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 4387d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 438820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 438920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 4390d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 4391d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 4392d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 4393d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 4394d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 4395d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 4396d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 4397d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 4398d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 43998adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 4400d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 4401d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 4402d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 4403d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 44043912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 44053912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 44063912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 44073912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 44083912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 44093912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 44103912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 44113912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 441272f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 441320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 441420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 441520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 4416f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 4417f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 4418f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 441972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 442072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 442172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 442220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 442320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 442420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 442572f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 4426f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 4427f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 442820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 442920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 443020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 4431f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 4432f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 443320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 443420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 443520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 443620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 443720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 443820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 443920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 444020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 444120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 444220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 444320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 444420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 444520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 444620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 444720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 444864944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 444920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 445020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 445120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 445220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 445320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 445420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 445520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 445620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 445720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 445864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 445964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 446064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 446164944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 446264944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 446364944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 446464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 446564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 446664944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 446764944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 446864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 446964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 447064944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 447164944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 44721de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) || 447364944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 447464944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 447564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 447664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 447764944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 447864944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 447964944f48a1164c02c15ca423a53919682a89074cJim Grosbach 44807f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // Also check the 'mul' syntax variant that doesn't specify an explicit 44817f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // destination register. 44827f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 && 44837f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 44847f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 44857f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 44867f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // If the registers aren't low regs or the cc_out operand is zero 44877f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 44887f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // remove the cc_out operand. 44897f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 44907f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 44917f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach !inITBlock())) 44927f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach return true; 44937f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach 449464944f48a1164c02c15ca423a53919682a89074cJim Grosbach 449520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 4496f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 4497f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 4498f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 4499f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 4500f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 4501f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 4502f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 450372f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 450472f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 450572f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 450672f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 45073912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 4508d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 4509d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 4510d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 45117aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) { 45127aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" || 45137aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" || 45147aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" || 45157aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" || 45167aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" || 45177aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".f" || Tok == ".d"; 45187aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach} 45197aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 45207aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class 45217aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be 45227aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now. 45237aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) { 45247aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm"); 45257aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach} 45267aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 452721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features); 4528badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 4529badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 4530badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 453121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // Apply mnemonic aliases before doing anything else, as the destination 453221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // mnemnonic may include suffices and we want to handle them normally. 453321d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // The generic tblgen'erated code does this later, at the start of 453421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // MatchInstructionImpl(), but that's too late for aliases that include 453521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach // any sort of suffix. 453621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach unsigned AvailableFeatures = getAvailableFeatures(); 453721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach applyMnemonicAliases(Name, AvailableFeatures); 453821d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach 4539badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 4540badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 4541ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 4542badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 4543352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 4544352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 4545a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 4546352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 454789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 45481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 454989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 4550badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 45510c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 45520c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 45530c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 45540c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 45550c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 45560c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 4557ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 4558ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 455989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 456089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 456189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 456289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 456389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 456489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 4565f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 4566f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 4567f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 4568f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 4569f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 457089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 457189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 457289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 457389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 457489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 4575f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 457689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 457789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 457889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 457989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 458089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4581f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 458289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 458389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4584ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 4585ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 45869717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 45873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 45883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 45893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 45903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 45913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 45923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 45933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 45943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 45951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 45963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 459733c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 459833c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 459933c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 460033c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 4601ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 460233c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 460333c16a27370939de39679245c3dff72383c210bdJim Grosbach } 4604c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 4605c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 4606c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 4607c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 4608c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 4609c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 4610c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 461133c16a27370939de39679245c3dff72383c210bdJim Grosbach 46123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 4613f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 4614f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 46153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 4616f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 4617f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 46183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 46193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 46203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 4621f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 4622f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 46233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 4624f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 4625badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 4626345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4627a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 4628a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 4629a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 4630a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 4631a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 4632a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4633a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 4634345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 46355747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 46365747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 46375747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 4638a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 4639a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 46407aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach // Some NEON instructions have an optional datatype suffix that is 46417aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach // completely ignored. Check for that. 46427aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach if (isDataTypeToken(ExtraToken) && 46437aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken)) 46447aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach continue; 46457aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 464681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 464781d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 464881d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 464981d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 46505747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 46515747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 46525747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 46535747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 4654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 46551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4656cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4657cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4658cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4660a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 4661b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 4662a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4663a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 46641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4665cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4666cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4667cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4668a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4669a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 467016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4671cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 4672186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach SMLoc Loc = getLexer().getLoc(); 4673cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4674186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach return Error(Loc, "unexpected token in argument list"); 4675cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4676146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 467734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 4678ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4679d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 4680d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 4681d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 468220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 468320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 468420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 468520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 468620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 4687ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4688ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 4689ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 4690ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 4691ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4692cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 4693cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 4694cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 469521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // a k_CondCode operand in the list. If we're trying to match the label 469621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // version, remove the k_CondCode operand here. 4697cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 4698cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 4699cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4700cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 4701cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 4702cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 4703857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 4704857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 4705857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 4706857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 4707857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 4708857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 4709857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4710857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4711857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4712857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 4713857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 4714857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 471568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 471668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 471768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 471868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 471968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 472068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 472168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 472268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 472368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 472468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 472568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4726857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 4727857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4728857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4729934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 473055b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach // end. Convert it to a token here. Take care not to convert those 473155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach // that should hit the Thumb2 encoding. 4732934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 473355b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 473455b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 4735934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4736934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4737934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 473855b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach if (CE && CE->getValue() == 0 && 473955b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach (isThumbOne() || 4740d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach // The cc_out operand matches the IT block. 4741d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach ((inITBlock() != CarrySetting) && 4742d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach // Neither register operand is a high register. 474355b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 4744d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){ 4745934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 4746934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4747934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 4748934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4749934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4750934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 47519898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 4752ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4753ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4754189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 4755aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 4756aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 4757aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 4758aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 4759aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 4760aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 4761aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 4762aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 4763aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 4764aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 4765aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 4766aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 4767aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 4768aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 4769aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 4770aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 4771aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 4772aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 477376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 477476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 477576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 477676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 477776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 477876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 477976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 478076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 478176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 478276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 478376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 4784f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 4785f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 4786f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 4787f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 47881a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[]; 4789f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 47901a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) { 4791f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 4792f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 4793f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4794189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 4795189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 4796189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 4797189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 47981a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 4799f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 4800f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 4801b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 4802b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 4803b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 4804b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 4805f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 4806f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 4807f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 4808f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 4809a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 4810f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 4811f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 4812f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 4813f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 4814f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 4815f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 4816f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 4817f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 4818f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 4819f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 4820f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 4821f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 4822f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 4823f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 4824f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 4825f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 4826f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 4827c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 4828f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 4829f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 483051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 483151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 4832f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 4833f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4834189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 48352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 48362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 48372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 4838189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 4839189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4840189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 4841189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4842189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 4843189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 4844189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 4845189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4846189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 484714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 484814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 484914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 485014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 485114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 485214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 485314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 485414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 485514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 485653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 485753642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 4858189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 4859189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4860189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4861189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 4862189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 486314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 4864189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 4865189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4866189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4867fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 4868fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 4869fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 4870fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 4871fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 4872fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 4873fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 4874fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 487500c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 4876fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 487793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 487876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 487976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 488076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 488176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 488276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 488393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 488493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 488593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 48867260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 48877260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 48887260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 4889aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 489076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 4891aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 4892aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 489393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 489476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 489593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 489693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 489776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 489876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 4899aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 49007260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 49017260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 49027260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 490393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 490493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 490593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 490676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 490776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 490876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 490976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 491076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 491176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 491276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 49135402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2, 49145402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // so only issue a diagnostic for thumb1. The instructions will be 49155402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // switched to the t2 encodings in processInstruction() if necessary. 49166dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 4917aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 49185402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) && 49195402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach !isThumbTwo()) 4920aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4921aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 49226dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 49236dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 49246dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 4925aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 49265402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) && 49275402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach !isThumbTwo()) 4928aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4929aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 49306dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 49316dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 49321e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 49331e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 49348213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 49351e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 49361e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 49371e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 49381e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 4939189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4940189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4941189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4942189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 4943189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 494484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbachstatic unsigned getRealVSTLNOpcode(unsigned Opc) { 494584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach switch(Opc) { 494684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach default: assert(0 && "unexpected opcode!"); 494784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_8: return ARM::VST1LNd8_UPD; 494884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P8: return ARM::VST1LNd8_UPD; 494984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I8: return ARM::VST1LNd8_UPD; 495084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S8: return ARM::VST1LNd8_UPD; 495184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U8: return ARM::VST1LNd8_UPD; 495284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_16: return ARM::VST1LNd16_UPD; 495384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P16: return ARM::VST1LNd16_UPD; 495484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I16: return ARM::VST1LNd16_UPD; 495584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S16: return ARM::VST1LNd16_UPD; 495684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U16: return ARM::VST1LNd16_UPD; 495784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_32: return ARM::VST1LNd32_UPD; 495884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F: return ARM::VST1LNd32_UPD; 495984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F32: return ARM::VST1LNd32_UPD; 496084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I32: return ARM::VST1LNd32_UPD; 496184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S32: return ARM::VST1LNd32_UPD; 496284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U32: return ARM::VST1LNd32_UPD; 496384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_8: return ARM::VST1LNd8_UPD; 496484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_P8: return ARM::VST1LNd8_UPD; 496584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I8: return ARM::VST1LNd8_UPD; 496684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S8: return ARM::VST1LNd8_UPD; 496784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U8: return ARM::VST1LNd8_UPD; 496884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_16: return ARM::VST1LNd16_UPD; 496984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_P16: return ARM::VST1LNd16_UPD; 497084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I16: return ARM::VST1LNd16_UPD; 497184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S16: return ARM::VST1LNd16_UPD; 497284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U16: return ARM::VST1LNd16_UPD; 497384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_32: return ARM::VST1LNd32_UPD; 497484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_F: return ARM::VST1LNd32_UPD; 497584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_F32: return ARM::VST1LNd32_UPD; 497684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I32: return ARM::VST1LNd32_UPD; 497784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S32: return ARM::VST1LNd32_UPD; 497884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U32: return ARM::VST1LNd32_UPD; 497984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_8: return ARM::VST1LNd8; 498084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_P8: return ARM::VST1LNd8; 498184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I8: return ARM::VST1LNd8; 498284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S8: return ARM::VST1LNd8; 498384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U8: return ARM::VST1LNd8; 498484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_16: return ARM::VST1LNd16; 498584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_P16: return ARM::VST1LNd16; 498684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I16: return ARM::VST1LNd16; 498784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S16: return ARM::VST1LNd16; 498884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U16: return ARM::VST1LNd16; 498984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_32: return ARM::VST1LNd32; 499084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_F: return ARM::VST1LNd32; 499184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_F32: return ARM::VST1LNd32; 499284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I32: return ARM::VST1LNd32; 499384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S32: return ARM::VST1LNd32; 499484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U32: return ARM::VST1LNd32; 499584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 499684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach} 499784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach 499884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbachstatic unsigned getRealVLDLNOpcode(unsigned Opc) { 49997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach switch(Opc) { 50007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach default: assert(0 && "unexpected opcode!"); 5001872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_8: return ARM::VLD1LNd8_UPD; 5002872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P8: return ARM::VLD1LNd8_UPD; 5003872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I8: return ARM::VLD1LNd8_UPD; 5004872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S8: return ARM::VLD1LNd8_UPD; 5005872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U8: return ARM::VLD1LNd8_UPD; 5006872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_16: return ARM::VLD1LNd16_UPD; 5007872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P16: return ARM::VLD1LNd16_UPD; 5008872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I16: return ARM::VLD1LNd16_UPD; 5009872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S16: return ARM::VLD1LNd16_UPD; 5010872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U16: return ARM::VLD1LNd16_UPD; 5011872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_32: return ARM::VLD1LNd32_UPD; 5012872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F: return ARM::VLD1LNd32_UPD; 5013872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F32: return ARM::VLD1LNd32_UPD; 5014872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I32: return ARM::VLD1LNd32_UPD; 5015872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S32: return ARM::VLD1LNd32_UPD; 5016872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U32: return ARM::VLD1LNd32_UPD; 5017872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_8: return ARM::VLD1LNd8_UPD; 5018872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_P8: return ARM::VLD1LNd8_UPD; 5019872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I8: return ARM::VLD1LNd8_UPD; 5020872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S8: return ARM::VLD1LNd8_UPD; 5021872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U8: return ARM::VLD1LNd8_UPD; 5022872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_16: return ARM::VLD1LNd16_UPD; 5023872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_P16: return ARM::VLD1LNd16_UPD; 5024872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I16: return ARM::VLD1LNd16_UPD; 5025872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S16: return ARM::VLD1LNd16_UPD; 5026872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U16: return ARM::VLD1LNd16_UPD; 5027872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_32: return ARM::VLD1LNd32_UPD; 5028872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_F: return ARM::VLD1LNd32_UPD; 5029872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_F32: return ARM::VLD1LNd32_UPD; 5030872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I32: return ARM::VLD1LNd32_UPD; 5031872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S32: return ARM::VLD1LNd32_UPD; 5032872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U32: return ARM::VLD1LNd32_UPD; 5033dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_8: return ARM::VLD1LNd8; 5034dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_P8: return ARM::VLD1LNd8; 5035dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I8: return ARM::VLD1LNd8; 5036dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S8: return ARM::VLD1LNd8; 5037dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U8: return ARM::VLD1LNd8; 5038872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_16: return ARM::VLD1LNd16; 5039872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_P16: return ARM::VLD1LNd16; 5040872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_I16: return ARM::VLD1LNd16; 5041872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_S16: return ARM::VLD1LNd16; 5042872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdAsm_U16: return ARM::VLD1LNd16; 5043dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_32: return ARM::VLD1LNd32; 5044dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_F: return ARM::VLD1LNd32; 5045dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_F32: return ARM::VLD1LNd32; 5046dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I32: return ARM::VLD1LNd32; 5047dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S32: return ARM::VLD1LNd32; 5048dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U32: return ARM::VLD1LNd32; 50497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 50507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach} 50517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach 505283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser:: 5053f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 5054f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 5055f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 505684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Handle NEON VST1 complex aliases. 505784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_8: 505884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_P8: 505984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I8: 506084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S8: 506184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U8: 506284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_16: 506384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_P16: 506484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I16: 506584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S16: 506684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U16: 506784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_32: 506884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_F: 506984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_F32: 507084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_I32: 507184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_S32: 507284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_register_Asm_U32: { 507384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 507484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 507584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 507684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode())); 507784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 507884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 507984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 508084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rm 508184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 508284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 508384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // CondCode 508484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 508584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 508684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 508784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 508884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_8: 508984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P8: 509084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I8: 509184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S8: 509284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U8: 509384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_16: 509484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_P16: 509584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I16: 509684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S16: 509784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U16: 509884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_32: 509984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F: 510084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_F32: 510184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_I32: 510284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_S32: 510384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdWB_fixed_Asm_U32: { 510484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 510584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 510684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 510784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode())); 510884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 510984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 511084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 511184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 511284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 511384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 511484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 511584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 511684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 511784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 511884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 511984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_8: 512084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_P8: 512184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I8: 512284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S8: 512384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U8: 512484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_16: 512584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_P16: 512684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I16: 512784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S16: 512884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U16: 512984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_32: 513084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_F: 513184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_F32: 513284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_I32: 513384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_S32: 513484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach case ARM::VST1LNdAsm_U32: { 513584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach MCInst TmpInst; 513684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // Shuffle the operands around so the lane index operand is in the 513784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach // right place. 513884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode())); 513984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 514084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 514184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 514284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 514384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 514484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 514584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach Inst = TmpInst; 514684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach return true; 514784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach } 51487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // Handle NEON VLD1 complex aliases. 5149872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_8: 5150872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_P8: 5151872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I8: 5152872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S8: 5153872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U8: 5154872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_16: 5155872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_P16: 5156872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I16: 5157872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S16: 5158872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U16: 5159872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_32: 5160872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_F: 5161872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_F32: 5162872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_I32: 5163872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_S32: 5164872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_register_Asm_U32: { 5165872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach MCInst TmpInst; 5166872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // Shuffle the operands around so the lane index operand is in the 5167872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // right place. 516884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode())); 5169872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 5170872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 5171872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 5172872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 5173872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rm 5174872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 5175872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 5176872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // CondCode 5177872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(6)); 5178872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach Inst = TmpInst; 5179872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach return true; 5180872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach } 5181872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_8: 5182872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P8: 5183872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I8: 5184872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S8: 5185872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U8: 5186872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_16: 5187872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_P16: 5188872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I16: 5189872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S16: 5190872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U16: 5191872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_32: 5192872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F: 5193872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_F32: 5194872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_I32: 5195872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_S32: 5196872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach case ARM::VLD1LNdWB_fixed_Asm_U32: { 5197872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach MCInst TmpInst; 5198872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // Shuffle the operands around so the lane index operand is in the 5199872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach // right place. 520084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode())); 5201872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 5202872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 5203872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 5204872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 5205872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 5206872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 5207872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 5208872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 5209872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 5210872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach Inst = TmpInst; 5211872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach return true; 5212872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach } 5213dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_8: 5214dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_P8: 5215dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I8: 5216dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S8: 5217dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U8: 5218dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_16: 5219dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_P16: 5220dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I16: 5221dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S16: 5222dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U16: 5223dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_32: 5224dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_F: 5225dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_F32: 5226dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_I32: 5227dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_S32: 5228dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach case ARM::VLD1LNdAsm_U32: { 52297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach MCInst TmpInst; 52307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // Shuffle the operands around so the lane index operand is in the 52317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach // right place. 523284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode())); 52337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Vd 52347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rn 52357636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // alignment 52367636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 52377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // lane 52387636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // CondCode 52397636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); 52407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach Inst = TmpInst; 52417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach return true; 52427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach } 524371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach // Handle the MOV complex aliases. 524423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::ASRr: 524523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSRr: 524623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSLr: 524723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::RORr: { 524823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 524923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach switch(Inst.getOpcode()) { 525023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 525123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::ASRr: ShiftTy = ARM_AM::asr; break; 525223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSRr: ShiftTy = ARM_AM::lsr; break; 525323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::LSLr: ShiftTy = ARM_AM::lsl; break; 525423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach case ARM::RORr: ShiftTy = ARM_AM::ror; break; 525523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach } 525623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach // A shift by zero is a plain MOVr, not a MOVsi. 525723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0); 525823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach MCInst TmpInst; 525923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.setOpcode(ARM::MOVsr); 526023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 526123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 526223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // Rm 526323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 526423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // CondCode 526523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 526623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // cc_out 526723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach Inst = TmpInst; 526823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach return true; 526923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach } 5270ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::ASRi: 5271ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSRi: 5272ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSLi: 5273ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::RORi: { 5274ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 5275ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach switch(Inst.getOpcode()) { 5276ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 5277ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::ASRi: ShiftTy = ARM_AM::asr; break; 5278ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSRi: ShiftTy = ARM_AM::lsr; break; 5279ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSLi: ShiftTy = ARM_AM::lsl; break; 5280ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::RORi: ShiftTy = ARM_AM::ror; break; 5281ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach } 5282ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach // A shift by zero is a plain MOVr, not a MOVsi. 528348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach unsigned Amt = Inst.getOperand(2).getImm(); 5284ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi; 5285ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt); 528671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach MCInst TmpInst; 5287ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach TmpInst.setOpcode(Opc); 528871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 528971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 5290ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (Opc == ARM::MOVsi) 5291ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 529271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // CondCode 529371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 529471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // cc_out 529571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach Inst = TmpInst; 529683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 529771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach } 529848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach case ARM::RRXi: { 529948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0); 530048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach MCInst TmpInst; 530148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.setOpcode(ARM::MOVsi); 530248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 530348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 530448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 530548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 530648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 530748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // cc_out 530848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach Inst = TmpInst; 530948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach return true; 531048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach } 53110352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach case ARM::t2LDMIA_UPD: { 53120352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // If this is a load of a single register, then we should use 53130352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 53140352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach if (Inst.getNumOperands() != 5) 53150352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return false; 53160352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach MCInst TmpInst; 53170352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.setOpcode(ARM::t2LDR_POST); 53180352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 53190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 53200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 53210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 53220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 53230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 53240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach Inst = TmpInst; 53250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return true; 53260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach } 53270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach case ARM::t2STMDB_UPD: { 53280352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // If this is a store of a single register, then we should use 53290352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 53300352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach if (Inst.getNumOperands() != 5) 53310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return false; 53320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach MCInst TmpInst; 53330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.setOpcode(ARM::t2STR_PRE); 53340352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 53350352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 53360352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 53370352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 53380352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 53390352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 53400352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach Inst = TmpInst; 53410352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return true; 53420352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach } 5343f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 5344f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 5345f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 5346f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 5347f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 5348f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 5349f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 5350f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 5351f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 5352f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 5353f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 5354f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 5355f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 5356f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5357f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 535883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 5359f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 5360f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 5361f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 5362f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 5363f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 5364f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 5365f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 5366f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 5367f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 5368f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 5369f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 5370f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 5371f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 5372f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 5373f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5374f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 5375f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 5376f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 5377da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach case ARM::t2ADDri12: 5378da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // If the immediate fits for encoding T3 (t2ADDri) and the generic "add" 5379da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // mnemonic was used (not "addw"), encoding T3 is preferred. 5380da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" || 5381da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 5382da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5383da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.setOpcode(ARM::t2ADDri); 5384da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 5385da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5386da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach case ARM::t2SUBri12: 5387da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub" 5388da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach // mnemonic was used (not "subw"), encoding T3 is preferred. 5389da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" || 5390da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 5391da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 5392da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.setOpcode(ARM::t2SUBri); 5393da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 5394da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach break; 539589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 53960f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 53970f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 53980f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 53990f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 540083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 540189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 540283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 540383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 540489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 5405f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 5406f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 5407f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 5408f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 5409f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 541083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 5411f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 541283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 541383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 5414f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 5415927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach case ARM::t2ADDrr: { 5416927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // If the destination and first source operand are the same, and 5417927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // there's no setting of the flags, use encoding T2 instead of T3. 5418927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // Note that this is only for ADD, not SUB. This mirrors the system 5419927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach // 'as' behaviour. Make sure the wide encoding wasn't explicit. 5420927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() || 5421927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach Inst.getOperand(5).getReg() != 0 || 5422713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 5423713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == ".w")) 5424927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach break; 5425927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach MCInst TmpInst; 5426927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.setOpcode(ARM::tADDhirr); 5427927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 5428927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 5429927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 5430927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5431927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 5432927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach Inst = TmpInst; 5433927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach return true; 5434927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach } 543551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 543651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 543783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) { 543851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 543983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 544083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 544151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 544251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 544351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 544483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){ 544551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 544683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 544783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 544851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 5449c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 5450a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 545183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) { 5452c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 545383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 545483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 5455c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 5456395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 5457395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 545883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) { 5459395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 546083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 546183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 54623ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 546376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 546476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 546576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 546676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 546776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 546876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 546976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 547076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 547176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 547276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 547376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 547476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 547576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 547676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 547776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 547876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 547976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 548076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 548176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 548276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 548376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 548483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 548576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 548676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 548776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 54888213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 54898213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 54908213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 54918213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 54928213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 54938213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 54948213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 54958213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 54968213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 54978213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 549883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 54998213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 55008213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 55018213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 55025402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach case ARM::tPOP: { 55035402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach bool listContainsBase; 55045402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // If the register list contains any high registers, we need to use 55055402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 55065402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // should have generated an error in validateInstruction(). 55075402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase)) 550883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 55095402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach assert (isThumbTwo()); 55105402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.setOpcode(ARM::t2LDMIA_UPD); 55115402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Add the base register and writeback operands. 55125402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 55135402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 551483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55155402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach } 55165402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach case ARM::tPUSH: { 55175402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach bool listContainsBase; 55185402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase)) 551983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 55205402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach assert (isThumbTwo()); 55215402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.setOpcode(ARM::t2STMDB_UPD); 55225402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Add the base register and writeback operands. 55235402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 55245402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 552583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55265402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach } 55271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 55281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 55291ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 55301ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 55311ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 5532c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 5533c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 5534c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 55351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 55361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 55371ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 55381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 55391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 55401ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 55411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 55421ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 55431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 55441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 55451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 554683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 55481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 55491ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 55501ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 55511ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 55521ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 55531ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 55541ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 55551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 55561ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 55571ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 55581ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 55591ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 55601ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 55611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 55621ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 55631ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 55641ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 55651ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 55661ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 556783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 55681ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 55691ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 55701ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 5571326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 557250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 557350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 557450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 5575326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 5576326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 5577326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 5578326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 5579326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 5580326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 5581326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 558250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 558350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 558450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 558550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 558650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 558750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 558850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 558950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 5590326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 5591326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 5592326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 5593326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 5594326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 5595326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 5596326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 5597326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 559883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 5599326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 5600326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 5601326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 560289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 560389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 560489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 560589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 560689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 560789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 560889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 560989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 561089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 5611f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 5612f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 561389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 561489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 561589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 561689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 561789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 561889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 561989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 5620f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 5621f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 5622f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 5623f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 5624f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 5625f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 5626f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 5627f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 562889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 562989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 5630f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 563183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 5632f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 5633f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 563447a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 563547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 563647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 5637194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 56381a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCInstrDesc &MCID = getInstDesc(Opc); 563947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 564047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 564147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 564247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 564347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 564447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 564547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 564647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 564747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 564847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 564947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 565047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 565147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 565247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 565347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 565447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 5655f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 5656f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 565747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 5658f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 5659f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 5660f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 566147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 5662194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 5663194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 5664194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 5665194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 5666194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 5667194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 5668194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 56694ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 5670194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 5671194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 5672194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 567347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 567447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 567547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 5676fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 5677fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 5678fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 5679fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 5680fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 5681fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 568219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 5683193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 5684193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 568519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 5686e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 5687189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 5688189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 5689a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 5690a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 5691a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 5692a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 5693189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 5694a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 5695189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 5696f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 569783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // encoding is selected. Loop on it while changes happen so the 569883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // individual transformations can chain off each other. E.g., 569983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8) 570083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach while (processInstruction(Inst, Operands)) 570183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach ; 5702f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 5703a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 5704a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 5705a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 5706a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 5707a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 5708fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 5709fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 5710e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 5711e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 5712e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 5713e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 5714e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 5715e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 5716e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 5717e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 571816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5719e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 5720e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 5721e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 572216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5723e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 5724e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 5725e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 572647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 5727b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 572888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 572988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 5730f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 5731f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 573247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 573347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 5734194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 5735194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 5736194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 5737194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 5738fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 573916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5740c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 5741146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 5742fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 5743fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 57441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 5745ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 5746ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 5747ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 57481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 5749515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 57501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 57519a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach else if (IDVal == ".arm") 57529a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return parseDirectiveARM(DirectiveID.getLoc()); 5753515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 57541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 5755515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 57561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 5757515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 57581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 5759ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 5760ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 5761ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 57621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 5763ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 57641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 5765ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 5766ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 5767ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 5768ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 5769ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 5770ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5771aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 5772ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5773ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 5774ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 577516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5776ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 5777ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 5778ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 5779b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5780ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 5781ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 5782ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5783b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5784ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 5785ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 5786ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 57871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 5788515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 57891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 5790515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 5791515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 5792b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5793515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 57949a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (!isThumb()) 57959a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach SwitchMode(); 57969a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 57979a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return false; 57989a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach} 57999a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach 58009a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM 58019a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// ::= .arm 58029a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) { 58039a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) 58049a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach return Error(L, "unexpected token in directive"); 58059a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach Parser.Lex(); 58069a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach 58079a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach if (isThumb()) 58089a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach SwitchMode(); 58099a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 5810515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5812515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 5814515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 58151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 58166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 58176469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 58186469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 58196469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 58206469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 58216469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 58226469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 58236469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 58246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 58256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 5826d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach Name = Tok.getIdentifier(); 58276469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 58286469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 58296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 5830d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) 5831515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 5832b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5833515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58346469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 58356469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 5836d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach Name = Parser.getTok().getIdentifier(); 58376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 58386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 5839642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 5840642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 5841642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 5842515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5843515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5844515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 5846515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 58471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 584818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5849515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 5850515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 585138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 585258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 5853b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 585458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 58559e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 5856515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 5857515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 5858515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5859515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 586018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 5861b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5862515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5863515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 5864515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 5865515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5866515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5867515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 58681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 5869515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 58701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 587118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5872515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 5873515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 587418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 587558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 5876b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 587758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 5878b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5879515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 5880515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 5881515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5882515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 588318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 5884b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5885515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 588632869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 588798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 5888ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 588998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 589032869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 589198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 5892ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 589398447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 5894eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 58952a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 5896515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5897515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5898515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 589990b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 590090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 59019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 5902ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 590394b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 590494b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 590590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 5906ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 59073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 59080692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 59090692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 59103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 5911