ARMAsmParser.cpp revision 6cb4b081829880ba97a729bcf33fd59517ca5450
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 4294b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 43ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 46f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach struct { 47f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes Cond; // Condition for IT block. 48f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Mask:4; // Condition mask for instructions. 49f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Starting at first 1 (from lsb). 50f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '1' condition as indicated in IT. 51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '0' inverse of condition (else). 52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Count of instructions in IT block is 53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // 4 - trailingzeroes(mask) 54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool FirstCond; // Explicit flag for when we're parsing the 56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // First instruction in the IT block. It's 57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // implied in the mask, so needs special 58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // handling. 59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned CurPosition; // Current position in parsing of IT 61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // block. In range [0,3]. Initialized 62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // according to count of instructions in block. 63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // ~0U if no active IT block. 64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } ITState; 65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool inITBlock() { return ITState.CurPosition != ~0U;} 66a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach void forwardITPosition() { 67a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (!inITBlock()) return; 68a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Move to the next instruction in the IT block, if there is one. If not, 69a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // mark the block as done. 70a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach unsigned TZ = CountTrailingZeros_32(ITState.Mask); 71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (++ITState.CurPosition == 5 - TZ) 72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach ITState.CurPosition = ~0U; // Done with the IT block after this. 73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 74f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 75f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 76ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 77ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 78ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 79ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 840d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 96515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 9889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool &CarrySetting, unsigned &ProcessorIMod, 9989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask); 1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 101fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 10216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 103ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 104ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 105ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 106ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 107ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 108ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 109ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 11047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 11147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 11247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 113194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 114194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 115194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 116acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool hasV7Ops() const { 117acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::HasV7Ops; 118acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 11932869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 120ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 121ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 12232869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 123acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool isMClass() const { 124acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::FeatureMClass; 125acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 126ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1293483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1300692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1310692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 13589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 13643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 137f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 13843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 139f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 1409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OperandMatchResultTy parseCoprocOptionOperand( 1419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 14243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1438bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1458bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1478bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 148f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 149f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 150f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 155f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 156c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 157580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 159293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 161251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 1629d39036f62674606565217a10db28171b9594bc7Jim Grosbach OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 163862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&); 164ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 165ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 166a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 167a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 168a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 169a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 170eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 171eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 172ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 173ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 175ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1769ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 1779ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &); 178548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 179548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 181ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1827b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 19514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 196623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 197623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 19988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20012431329d617064d6e72dd040a58c1635cc261abJim Grosbach bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode, 20112431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 20212431329d617064d6e72dd040a58c1635cc261abJim Grosbach bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, 20312431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2044334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, 2054334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 2064334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, 2074334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 208189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 209189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 210189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 21183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach bool processInstruction(MCInst &Inst, 212f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 213d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 214d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 215189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 216ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 21747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 218194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 219f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Match_RequiresNotITBlock, 220194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 221194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 22247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 22347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 224ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 22594b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 226ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 22732869205052430f45d598fba25ab878d8b29da2dEvan Cheng 228ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 229ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 230f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 231f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Not in an ITBlock to start with. 232f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = ~0U; 233ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 234ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 2361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 2371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 238189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 2391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 2401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 24147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 24247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 2431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 2441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 246ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 24716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 24816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2493a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 2503a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 251a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 252a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 253146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 25521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CondCode, 25621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CCOut, 25721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ITCondMask, 25821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocNum, 25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocReg, 2609b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach k_CoprocOption, 26121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Immediate, 26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_FPImmediate, 26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MemBarrierOpt, 26421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Memory, 26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_PostIndexRegister, 26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MSRMask, 26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ProcIFlags, 268460a90540b045c102012da2492999557e6840526Jim Grosbach k_VectorIndex, 26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Register, 27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RegisterList, 27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_DPRRegisterList, 27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_SPRRegisterList, 273862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach k_VectorList, 27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedRegister, 27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedImmediate, 27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShifterImmediate, 27721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RotateImmediate, 27821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_BitfieldDescriptor, 27921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Token 280a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 281a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 282762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 28324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 284a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 285a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 286a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 291fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 292fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 293fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 294fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 2959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach unsigned Val; 2969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } CoprocOption; 2979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 2989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach struct { 29989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 30089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 30189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 30289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 30389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 30489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 30589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 30689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 307a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 308a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 309a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 310a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 311584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 312584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 315a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 317a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 319a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 323862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // A vector register list is a sequential list of 1 to 4 registers. 324862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach struct { 325862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned RegNum; 326862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count; 327862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } VectorList; 328862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 3298155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 330460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned Val; 331460a90540b045c102012da2492999557e6840526Jim Grosbach } VectorIndex; 332460a90540b045c102012da2492999557e6840526Jim Grosbach 333460a90540b045c102012da2492999557e6840526Jim Grosbach struct { 334cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 335cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 33616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3379d39036f62674606565217a10db28171b9594bc7Jim Grosbach struct { 3389d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned Val; // encoded 8-bit representation 3399d39036f62674606565217a10db28171b9594bc7Jim Grosbach } FPImm; 3409d39036f62674606565217a10db28171b9594bc7Jim Grosbach 3416a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 342a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 3447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 3457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 3467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 3477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 3487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 34957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned ShiftImm; // shift for OffsetReg. 35057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment; // 0 = no alignment specified 35157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // n = alignment in bytes (8, 16, or 32) 3527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 353e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach } Memory; 3540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 3550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 3567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 357f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 358f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 359f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 3607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 3617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 363580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 364e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 365580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 366e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 367e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 368e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 369e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 370e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 371af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 37292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 37392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 37492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 37592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 376af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 3777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 3787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 380293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 381293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 382293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 383293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 384a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 38516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 386146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 387146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 388762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 389762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 390762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 391762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 392762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 39321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 3948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 39621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: 39789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 39889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 39921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 4008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 401762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 40221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 40321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 404762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 405762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 40721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 40821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: 40924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 4108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 411862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 412862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach VectorList = o.VectorList; 413862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 41521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 416fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 417fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 4189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 4199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach CoprocOption = o.CoprocOption; 4209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 42121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 422762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 423762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 42421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 4259d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImm = o.FPImm; 4269d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 42721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 428706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 429706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 43021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 431e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory = o.Memory; 432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 43321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 4347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 4357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 43621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 437584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 438584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: 440a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 4410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 44221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 443580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 4440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 44521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 446af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 447e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 44821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 449af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 45092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 45121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 4527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 4537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 455293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 456293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 457460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 458460a90540b045c102012da2492999557e6840526Jim Grosbach VectorIndex = o.VectorIndex; 459460a90540b045c102012da2492999557e6840526Jim Grosbach break; 460762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 461762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 46216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 463762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 464762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 465762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 466762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 467a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 46921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_CondCode && "Invalid access!"); 4708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 4718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4728462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 473fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 47421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 475fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 476fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 477fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 478a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 47921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Token && "Invalid access!"); 480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 481a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 482a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 48421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 4857729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 486a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4885fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 48921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 49021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind == k_SPRRegisterList) && "Invalid access!"); 49124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 4928d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 4938d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 494cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 49521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Immediate && "Invalid access!"); 496cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 497cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 498cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 4999d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned getFPImm() const { 50021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_FPImmediate && "Invalid access!"); 5019d39036f62674606565217a10db28171b9594bc7Jim Grosbach return FPImm.Val; 5029d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 5039d39036f62674606565217a10db28171b9594bc7Jim Grosbach 504460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned getVectorIndex() const { 505460a90540b045c102012da2492999557e6840526Jim Grosbach assert(Kind == k_VectorIndex && "Invalid access!"); 506460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val; 507460a90540b045c102012da2492999557e6840526Jim Grosbach } 508460a90540b045c102012da2492999557e6840526Jim Grosbach 509706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 51021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MemBarrierOpt && "Invalid access!"); 511706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 512706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 513706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 514a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 51521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_ProcIFlags && "Invalid access!"); 516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 519584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 52021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MSRMask && "Invalid access!"); 521584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 522584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 523584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocNum() const { return Kind == k_CoprocNum; } 52521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocReg() const { return Kind == k_CoprocReg; } 5269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach bool isCoprocOption() const { return Kind == k_CoprocOption; } 52721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCondCode() const { return Kind == k_CondCode; } 52821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCCOut() const { return Kind == k_CCOut; } 52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITMask() const { return Kind == k_ITCondMask; } 53021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITCondCode() const { return Kind == k_CondCode; } 53121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isImm() const { return Kind == k_Immediate; } 53221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isFPImm() const { return Kind == k_FPImmediate; } 533a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isImm8s4() const { 53421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 535a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 536a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 537a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!CE) return false; 538a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Value = CE->getValue(); 539a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 540a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 54172f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 54221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 54372f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 54472f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 54572f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 54672f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 54772f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 54872f39f8436848885176943b0ba985a7171145423Jim Grosbach } 54972f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 55021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 55172f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 55272f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 55372f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 55472f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 55572f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 55672f39f8436848885176943b0ba985a7171145423Jim Grosbach } 5576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 55821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5606b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5616b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5626b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 5646b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 56583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 56621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 56783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 56883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 56983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 57083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 57183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 57283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 57383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 57421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 57583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 57683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 57783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 57883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 57983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 58083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 5817c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 58221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5837c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 5847c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5857c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 5867c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 5877c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 5887c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 589f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 59021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 591f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 592f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 593f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 594f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 595f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 596f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 5974a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 59821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5994a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 6004a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6014a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 6024a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 6034a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 6044a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 605ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach bool isImm0_32() const { 606ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (Kind != k_Immediate) 607ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach return false; 608ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 609ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (!CE) return false; 610ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach int64_t Value = CE->getValue(); 611ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach return Value >= 0 && Value < 33; 612ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach } 613fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 61421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 615fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 616fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 617fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 618fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 619fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 620fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 621ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 62221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 623ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 624ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 625ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 626ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 627ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 628ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 629ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 630ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 631ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 63221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 633ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 634ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 635ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 636ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 637ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 638ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 63970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 64021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 64170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 64270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 64370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 64470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 64570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 64670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 64821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 649f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 650f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 651f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 652f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 653f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 654f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 655f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 65621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 657f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 658f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 659f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 660f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 661f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 662f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 6636bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 66421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6656bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 6666bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6676bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 6686bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 6696bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 6706bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 671e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach bool isARMSOImmNot() const { 672e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach if (Kind != k_Immediate) 673e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach return false; 674e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 675e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach if (!CE) return false; 676e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach int64_t Value = CE->getValue(); 677e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach return ARM_AM::getSOImmVal(~Value) != -1; 678e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach } 6796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 68021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 6826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 6846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 6856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 6866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 68789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach bool isT2SOImmNot() const { 68889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach if (Kind != k_Immediate) 68989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach return false; 69089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 69189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach if (!CE) return false; 69289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach int64_t Value = CE->getValue(); 69389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach return ARM_AM::getT2SOImmVal(~Value) != -1; 69489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach } 695c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 69621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 697c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 698c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 699c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 700c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 701c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 702c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 70321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isReg() const { return Kind == k_Register; } 70421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegList() const { return Kind == k_RegisterList; } 70521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 70621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 70721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isToken() const { return Kind == k_Token; } 70821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 70921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemory() const { return Kind == k_Memory; } 71021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isShifterImm() const { return Kind == k_ShifterImmediate; } 71121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 71221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 71321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRotImm() const { return Kind == k_RotateImmediate; } 71421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 71521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 716f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 717430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift; 718f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 71957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isMemNoOffset(bool alignOK = false) const { 720f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 721ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 7227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 72357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 && 72457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach (alignOK || Memory.Alignment == 0); 72557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 72657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isAlignedMemory() const { 72757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return isMemNoOffset(true); 728ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 7297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 73057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 7317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 732e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 7337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 734e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 735e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 7367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 7377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 738039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 73921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 740039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 741039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 742039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 743039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 744039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 745039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 746039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 7472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 74857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 7492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 750e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::no_shift) return false; 7512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 752e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 7532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 754e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 755e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 7562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 7572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 75921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate && Kind != k_PostIndexRegister) 7602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 76121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) 7622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 7632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 7642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 7662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 767251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 768251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 7692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 771681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // If we have an immediate that's not a constant, treat it as a label 772681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // reference needing a fixup. If it is a constant, it's something else 773681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // and we reject it. 774681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 775681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach return true; 77657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 7777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 778e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return false; 7797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 780e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 781e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 7820da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 783681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Val == INT32_MIN; 7847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 7857f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBB() const { 786e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 78757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 7887f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7897f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7907f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7917f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBH() const { 792e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 79357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 79457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0 ) 7957f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7967f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7977f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 79957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0) 800ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 801ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 802ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 803ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach bool isT2MemRegOffset() const { 80457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 80557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0) 806ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 807ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach // Only lsl #{0, 1, 2, 3} allowed. 808e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType == ARM_AM::no_shift) 809ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 810e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 811ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 812ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 813ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 8147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 8157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 8167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 817e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 81857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 81987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 820e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach return isARMLowRegister(Memory.BaseRegNum) && 821e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 82260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 82360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 824e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 82557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 82660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 82760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 828e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 829e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 830ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 831ecd858968384be029574d845eb098d357049e02eJim Grosbach } 83238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 833e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 83457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 83538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 83638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 837e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 838e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 83938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 84038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 84148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 842e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 84357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 84448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 84548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 846e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 847e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 84848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 84948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 850ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 85157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 85257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 853ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 854ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 855e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 856e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 857ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 858505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 859a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isMemImm8s4Offset() const { 86057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 861a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 862a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate offset a multiple of 4 in range [-1020, 1020]. 863e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 864e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 865a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 866a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 867b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach bool isMemImm0_1020s4Offset() const { 86857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 869b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return false; 870b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // Immediate offset a multiple of 4 in range [0, 1020]. 871e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 872e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 873b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 874b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 8757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 87657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 877f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 8787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 879e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 880e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8814d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson return (Val == INT32_MIN) || (Val > -256 && Val < 256); 882f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 883f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach bool isMemPosImm8Offset() const { 88457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 885f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return false; 886f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach // Immediate offset in range [0, 255]. 887e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 888e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 889f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return Val >= 0 && Val < 256; 890f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 891a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemNegImm8Offset() const { 89257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 893a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 894a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [-255, -1]. 895e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 896e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 897a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return Val > -256 && Val < 0; 898a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 899a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemUImm12Offset() const { 90057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 901a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 902a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [0, 4095]. 903e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 904e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 905a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return (Val >= 0 && Val < 4096); 906a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 9077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 90809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 90909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 91009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 91121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 91209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 91309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 91457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 915ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 9167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 917e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 918e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 9190da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 9207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 9217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 92221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 9237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 9247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 925ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 9267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 92763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 928ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 9292bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isPostIdxImm8s4() const { 9302bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Kind != k_Immediate) 9312bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return false; 9322bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9332bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (!CE) return false; 9342bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int64_t Val = CE->getValue(); 9352bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 9362bd0118472de352745a2e038245fab4974f7c87eJim Grosbach (Val == INT32_MIN); 9372bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 9387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 93921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMSRMask() const { return Kind == k_MSRMask; } 94021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isProcIFlags() const { return Kind == k_ProcIFlags; } 9413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9420e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // NEON operands. 943862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach bool isVecListOneD() const { 944862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Kind != k_VectorList) return false; 945862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return VectorList.Count == 1; 946862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 947862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 948280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach bool isVecListTwoD() const { 949280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach if (Kind != k_VectorList) return false; 950280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach return VectorList.Count == 2; 951280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach } 952280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach 953cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach bool isVecListThreeD() const { 954cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach if (Kind != k_VectorList) return false; 955cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach return VectorList.Count == 3; 956cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach } 957cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach 958b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach bool isVecListFourD() const { 959b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach if (Kind != k_VectorList) return false; 960b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach return VectorList.Count == 4; 961b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach } 962b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach 9634661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach bool isVecListTwoQ() const { 9644661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach if (Kind != k_VectorList) return false; 9654661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach //FIXME: We haven't taught the parser to handle by-two register lists 9664661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach // yet, so don't pretend to know one. 9674661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach return VectorList.Count == 2 && false; 9684661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach } 9694661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach 970460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex8() const { 971460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 972460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 8; 973460a90540b045c102012da2492999557e6840526Jim Grosbach } 974460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex16() const { 975460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 976460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 4; 977460a90540b045c102012da2492999557e6840526Jim Grosbach } 978460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex32() const { 979460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 980460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 2; 981460a90540b045c102012da2492999557e6840526Jim Grosbach } 982460a90540b045c102012da2492999557e6840526Jim Grosbach 9830e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach bool isNEONi8splat() const { 9840e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (Kind != k_Immediate) 9850e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return false; 9860e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9870e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Must be a constant. 9880e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!CE) return false; 9890e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach int64_t Value = CE->getValue(); 9900e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // i8 value splatted across 8 bytes. The immediate is just the 8 byte 9910e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // value. 9920e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return Value >= 0 && Value < 256; 9930e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 994460a90540b045c102012da2492999557e6840526Jim Grosbach 995ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach bool isNEONi16splat() const { 996ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Kind != k_Immediate) 997ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return false; 998ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 999ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // Must be a constant. 1000ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (!CE) return false; 1001ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach int64_t Value = CE->getValue(); 1002ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // i16 value in the range [0,255] or [0x0100, 0xff00] 1003ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00); 1004ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1005ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 10066248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32splat() const { 10076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 10086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 10096248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10106248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 10116248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 10126248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 10136248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X. 10146248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 10156248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 10166248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 10176248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000); 10186248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 10196248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 10206248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32vmov() const { 10216248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 10226248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 10236248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10246248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 10256248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 10266248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 10276248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 10286248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 10296248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 10306248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 10316248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 10326248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000) || 10336248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 10346248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 10356248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 10366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1037f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach bool isNEONi64splat() const { 1038f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (Kind != k_Immediate) 1039f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return false; 1040f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1041f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // Must be a constant. 1042f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (!CE) return false; 1043f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1044f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // i64 value with each byte being either 0 or 0xff. 1045f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i) 1046f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 1047f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return true; 1048f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1049f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 10503483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 105114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 105214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 105314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 105414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 10553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 10563483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 10573483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 10583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 10593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 10608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1061345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 10628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 106304f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 106404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 10658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 10668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1067fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 1068fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1069fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 1070fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1071fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 10729b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 10739b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10749b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(getCoproc())); 10759b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 10769b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 10779b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 10789b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10799b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val)); 10809b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 10819b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 108289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 108389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 108489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 108589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 108689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 108789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 108889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 108989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 109089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 109189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 1092d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 1093d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1094d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 1095d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1096d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 1097a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 1098a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 1099a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 1100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1102af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 1103e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1104430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach assert(isRegShiftedReg() && 1105430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach "addRegShiftedRegOperands() on non RegShiftedReg!"); 1106af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 1107af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 1108e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 1109af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 1110e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1111e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1112af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 1113152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 1114430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach assert(isRegShiftedImm() && 1115430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach "addRegShiftedImmOperands() on non RegShiftedImm!"); 1116af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 111792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 1118af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 111992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 112092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1121580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 11220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 1123580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 1124580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 11250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 11260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 112787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 11287729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 11295fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 11305fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 11317729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 11327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 113387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 113487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 11350f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 11360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 11370f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 11380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 11390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 11400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 11410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 11420f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 11437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 11447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 11467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 11477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 11487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1149293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1150293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1151293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 1152293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 1153293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 1154293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1155293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1156293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 1157293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 1158293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1159293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 11603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 11616b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11626b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 11636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 11646b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 11659d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 11669d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11679d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 11689d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 11699d39036f62674606565217a10db28171b9594bc7Jim Grosbach 1170a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1171a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1172a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 1173a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 1174a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1175a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1176a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1177a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 117872f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 117972f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 118072f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 118172f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 118272f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 118372f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 118472f39f8436848885176943b0ba985a7171145423Jim Grosbach } 118572f39f8436848885176943b0ba985a7171145423Jim Grosbach 118672f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 118772f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 118872f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 118972f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 119072f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 119172f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 119272f39f8436848885176943b0ba985a7171145423Jim Grosbach } 119372f39f8436848885176943b0ba985a7171145423Jim Grosbach 1194f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1195f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1196f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1197f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1198f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1199f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1200f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1201f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 12024a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 12034a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 12044a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 12054a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 12064a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 12074a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 12084a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 12094a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 121070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 121170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 121270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 121370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 121470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 121570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 121670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1217ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1218ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1219f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1220f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1221f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1222f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1223f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1224f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1225f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1226f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1227f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 122889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const { 122989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 123089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach // The operand is actually a t2_so_imm, but we have its bitwise 123189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach // negation in the assembly source, so twiddle it here. 123289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 123389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 123489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach } 123589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach 1236e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const { 1237e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1238e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach // The operand is actually a so_imm, but we have its bitwise 1239e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach // negation in the assembly source, so twiddle it here. 1240e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1241e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 1242e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach } 1243e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach 1244706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1245706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1246706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1247706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1248706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 12497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 12507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1251e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1252505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1253505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 125457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 125557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 125657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 125757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 125857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 125957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 12607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 12617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1262e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1263e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 12647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 12667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 12677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 12687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 12697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 12707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 12717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 1272e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1273e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1274ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1275e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1276e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 12777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1278ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1279ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1280039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1281039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1282039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1283039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1284039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1285039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1286039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1287039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1288039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1289039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1290039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1291039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1292039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1293039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 12942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 12952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1296e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1297e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 12982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 13002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 13012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 13022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 13032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 13042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 13052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 1306e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 13072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 1308e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1309e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 13102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 13122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 13132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 13142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 131521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) { 13162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 13172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 13182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 13192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1320251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 13212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 13222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 13232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 13242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 13252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 13262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 13272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 13282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 13292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1330251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 13312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 13322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 13342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 13357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 13367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1337681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // If we have an immediate that's not a constant, treat it as a label 1338681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // reference needing a fixup. If it is a constant, it's something else 1339681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach // and we reject it. 1340681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach if (isImm()) { 1341681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Inst.addOperand(MCOperand::CreateExpr(getImm())); 1342681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1343681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach return; 1344681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach } 1345681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach 13467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1347e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 13487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 13497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 13507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 13517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 13527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 1353e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 13547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 13567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1357a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1358a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1359e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1360e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1361a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1362a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1363a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1364b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1365b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1366b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1367e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1368e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1369b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1370b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1371b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 13727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 13737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1374e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1375e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 13767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1377ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1378ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1379f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1380f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1381f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1382f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1383a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1384f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1385a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1386a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1387a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1388a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1389a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 139021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 1391a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1392a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1393a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1394a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1395a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1396a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1397e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1398e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1399a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1400a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1401a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 14027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 14037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 140409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 140521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 140609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 140709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 140809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 140909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 141009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 141109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1412e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1413e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 14147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 141692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 14177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 14187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1419e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1420e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14217f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 14227f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 14237f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 14247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1425e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1426e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14277f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 14287f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 14297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 14307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1431430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach unsigned Val = 1432430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1433430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach Memory.ShiftImm, Memory.ShiftType); 1434e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1435e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1438d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1439ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1440ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1441e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1442e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1443e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 1444ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1445ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 14467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 14477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1448e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1449e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 145014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 14513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 145260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 145360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1454e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1455e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 145660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 145748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 145848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 145938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 146038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1461e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 1462e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 146338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 146438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 146538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 146648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 146748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1468e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 1469e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 147048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 147160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 147260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1473ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1474ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1475e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1476e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1477ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1478ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1479ecd858968384be029574d845eb098d357049e02eJim Grosbach 14807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 14817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 14827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 14847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 14857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 148663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 14877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 14887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1489f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1490ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 14912bd0118472de352745a2e038245fab4974f7c87eJim Grosbach void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 14922bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 14932bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14942bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(CE && "non-constant post-idx-imm8s4 operand!"); 14952bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int Imm = CE->getValue(); 14962bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isAdd = Imm >= 0; 14972bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Imm == INT32_MIN) Imm = 0; 14982bd0118472de352745a2e038245fab4974f7c87eJim Grosbach // Immediate is scaled by 4. 14992bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 15002bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 15012bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 15022bd0118472de352745a2e038245fab4974f7c87eJim Grosbach 15037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 15047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 15057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1506f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1507f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1508f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1509f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1510f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1511f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1512f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1513f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1514f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1515f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1516f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1517f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1518ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1519ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1520584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1521584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1522584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1523584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1524584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1527a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1528a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1529a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1530862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach void addVecListOneDOperands(MCInst &Inst, unsigned N) const { 1531862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1532862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1533862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1534862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1535280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach void addVecListTwoDOperands(MCInst &Inst, unsigned N) const { 1536280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1537280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach // Only the first register actually goes on the instruction. The rest 1538280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach // are implied by the opcode. 1539280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1540280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach } 1541280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach 1542cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach void addVecListThreeDOperands(MCInst &Inst, unsigned N) const { 1543cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1544cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach // Only the first register actually goes on the instruction. The rest 1545cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach // are implied by the opcode. 1546cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1547cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach } 1548cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach 1549b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach void addVecListFourDOperands(MCInst &Inst, unsigned N) const { 1550b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1551b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach // Only the first register actually goes on the instruction. The rest 1552b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach // are implied by the opcode. 1553b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1554b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach } 1555b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach 15564661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach void addVecListTwoQOperands(MCInst &Inst, unsigned N) const { 15574661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 15584661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach // Only the first register actually goes on the instruction. The rest 15594661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach // are implied by the opcode. 15604661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 15614661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach } 15624661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach 1563460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1564460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1565460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1566460a90540b045c102012da2492999557e6840526Jim Grosbach } 1567460a90540b045c102012da2492999557e6840526Jim Grosbach 1568460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1569460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1570460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1571460a90540b045c102012da2492999557e6840526Jim Grosbach } 1572460a90540b045c102012da2492999557e6840526Jim Grosbach 1573460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1574460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1575460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1576460a90540b045c102012da2492999557e6840526Jim Grosbach } 1577460a90540b045c102012da2492999557e6840526Jim Grosbach 15780e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 15790e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 15800e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // The immediate encodes the type of constant as well as the value. 15810e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Mask in that this is an i8 splat. 15820e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 15830e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00)); 15840e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 15850e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 1586ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 1587ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1588ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // The immediate encodes the type of constant as well as the value. 1589ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1590ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach unsigned Value = CE->getValue(); 1591ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Value >= 256) 1592ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value = (Value >> 8) | 0xa00; 1593ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach else 1594ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value |= 0x800; 1595ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 1596ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1597ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 15986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 15996248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 16006248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 16016248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 16026248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 16036248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xff00) 16046248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | 0x200; 16056248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xff0000) 16066248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | 0x400; 16076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 16086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 16096248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 16106248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 16116248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 16126248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 16136248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 16146248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 16156248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 16166248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 16176248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xffff) 16186248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 16196248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xffffff) 16206248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 16216248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 16226248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 16236248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 16246248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 16256248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1626f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 1627f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1628f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // The immediate encodes the type of constant as well as the value. 1629f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1630f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1631f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach unsigned Imm = 0; 1632f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 1633f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Imm |= (Value & 1) << i; 1634f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1635f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00)); 1636f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1637f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 1638b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1639b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 164089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 164121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ITCondMask); 164289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 164389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 164489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 164589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 164689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 164789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 16483a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 164921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CondCode); 1650345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1651345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1652345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 16533a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1654345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1655345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1656fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 165721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocNum); 1658fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1659fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1660fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1661fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1662fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1663fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1664fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 166521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocReg); 1666fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1667fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1668fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1669fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1670fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1671fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 16729b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) { 16739b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocOption); 16749b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->Cop.Val = Val; 16759b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->StartLoc = S; 16769b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->EndLoc = E; 16779b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return Op; 16789b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 16799b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 1680d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 168121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CCOut); 1682d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1683d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1684d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1685d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1686d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1687d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 16883a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 168921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Token); 1690762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1691762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1692762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1693762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 16943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1695a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1696a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 169750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 169821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Register); 1699762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1700762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1701762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 17023a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1703a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1704a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1705e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1706e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1707e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1708e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1709e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 171021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1711af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1712af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1713af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1714af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1715e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1716e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1717e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1718e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1719e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 172092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 172192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 172292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 172392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 172421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1725af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1726af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1727af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 172892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 172992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 173092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 173192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 173292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1733580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 17340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 173521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1736580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1737580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 17380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 17390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 17400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 17410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 17420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 17437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 174421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_RotateImmediate); 17457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 17467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 17477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 17487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 17497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 17507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1751293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1752293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 175321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 1754293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1755293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1756293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1757293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1758293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1759293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1760293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 17617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 17625fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1763cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 176421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach KindTy Kind = k_RegisterList; 17650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1766d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 176721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_DPRRegisterList; 1768d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1769275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 177021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_SPRRegisterList; 17710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 17720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 17735fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 17747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 177524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1776cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1777cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1778cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 17798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 17808d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 17818d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 1782862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count, 1783862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc S, SMLoc E) { 1784862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorList); 1785862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.RegNum = RegNum; 1786862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.Count = Count; 1787862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->StartLoc = S; 1788862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->EndLoc = E; 1789862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return Op; 1790862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1791862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1792460a90540b045c102012da2492999557e6840526Jim Grosbach static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 1793460a90540b045c102012da2492999557e6840526Jim Grosbach MCContext &Ctx) { 1794460a90540b045c102012da2492999557e6840526Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorIndex); 1795460a90540b045c102012da2492999557e6840526Jim Grosbach Op->VectorIndex.Val = Idx; 1796460a90540b045c102012da2492999557e6840526Jim Grosbach Op->StartLoc = S; 1797460a90540b045c102012da2492999557e6840526Jim Grosbach Op->EndLoc = E; 1798460a90540b045c102012da2492999557e6840526Jim Grosbach return Op; 1799460a90540b045c102012da2492999557e6840526Jim Grosbach } 1800460a90540b045c102012da2492999557e6840526Jim Grosbach 18013a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 180221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Immediate); 1803762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1804762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1805762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 18063a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1807cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1808cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 18099d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 181021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_FPImmediate); 18119d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 18129d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 18139d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 18149d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 18159d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 18169d39036f62674606565217a10db28171b9594bc7Jim Grosbach 18177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 18187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 18197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 18207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 18210d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 182257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment, 18237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 18243a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 182521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Memory); 1826e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.BaseRegNum = BaseRegNum; 1827e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetImm = OffsetImm; 1828e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetRegNum = OffsetRegNum; 1829e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftType = ShiftType; 1830e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftImm = ShiftImm; 183157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Op->Memory.Alignment = Alignment; 1832e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.isNegative = isNegative; 18337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 18347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 18357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 18367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 183716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1838f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1839f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1840f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 18417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 184221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 18437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1844f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1845f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1846f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1847762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1848762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 18493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1850a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1851706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1852706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 185321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 1854706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1855706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1856706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1857706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1858706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1859a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1860a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 186121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ProcIFlags); 1862a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1863a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1864a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1865a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1866a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1867584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1868584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 186921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MSRMask); 1870584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1871584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1872584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1873584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1874584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1875a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1876a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1877a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1878a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1879b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1880fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 188121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 18829d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 18839d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 18849d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 188521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 18866a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1887fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 188821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 1889d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1890d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 189121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: { 18921a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer static const char *MaskStr[] = { 18931a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)", 18941a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)" 18951a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer }; 189689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 189789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 189889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 189989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 190021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 1901fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1902fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 190321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 1904fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1905fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 19069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 19079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OS << "<coprocessor option: " << CoprocOption.Val << ">"; 19089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 190921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 1910584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1911584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 191221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 1913fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1914fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 191521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 1916706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1917706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 191821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 19196ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 1920e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach << " base:" << Memory.BaseRegNum; 19216ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1922fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 192321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 1924f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1925f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1926f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1927f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1928f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1929f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 19307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 193121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: { 1932a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1933a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1934a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1935a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1936a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1937a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1938a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1939a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 194021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 194150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1942fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 194321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 1944580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1945580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1946e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 194721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 194892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1949af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1950af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1951af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1952af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1953e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 19540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 195521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 195692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1957af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1958af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1959af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 196092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 196192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 196221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 19637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 19647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 196521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 1966293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1967293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1968293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 196921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 197021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 197121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: { 19728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 19738d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 19745fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 19755fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 19767729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 19777729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 19787729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 19798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 19808d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 19818d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 19828d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 19838d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1984862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 1985862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OS << "<vector_list " << VectorList.Count << " * " 1986862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach << VectorList.RegNum << ">"; 1987862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 198821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 1989fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1990fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1991460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 1992460a90540b045c102012da2492999557e6840526Jim Grosbach OS << "<vectorindex " << getVectorIndex() << ">"; 1993460a90540b045c102012da2492999557e6840526Jim Grosbach break; 1994fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1995fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 19963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 19973483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 19983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 19993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 20003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 20013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 20023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 20033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 200469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 200569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 20061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 2007bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 2008bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 2009bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 2010bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 20119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 2012e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 2013e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 20143a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 20151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 201618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 20177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 2018d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 2019a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 2020a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 2021590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string lowerCase = Tok.getString().lower(); 20220c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 20230c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 20240c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 20250c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 20260c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 20270c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 20280c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 20290c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 20300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 20310c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 203269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 2033b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 2034460a90540b045c102012da2492999557e6840526Jim Grosbach 2035e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 2036e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 2037d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 203819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 203919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 204019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 204119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 204219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 20430d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 20440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 20450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 20460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 20470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 20480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2049590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string lowerCase = Tok.getString().lower(); 20500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 20510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 20520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 20530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 20540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 20550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 20560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 20570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 20580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 205919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 20600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2061e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 2062e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 2063e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 2064e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 2065e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 2066eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 2067e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 2068e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 2069e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 2070e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 2071e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 2072e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 2073e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 2074e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 2075e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 2076e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 2077e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 2078e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 2079e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2080e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 2081e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 2082e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 208319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 208419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 208519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 208619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2087e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 2088e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 208919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 209019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 209119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 209219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2093e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 2094e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 2095e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 2096e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 2097e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 2098e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 2099e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 210019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 210119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 2102e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2103e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 21041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 2105e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 210619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 210719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 210819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 210919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 211019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 211119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 2112e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 211319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 211419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2115e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2116e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 211792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 211892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 2119af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 21200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 212192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 212292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 212392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 21240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 212519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 21260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 21270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 21280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 212950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 213050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 213150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 2132e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 2133e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 2134e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 213550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 21361355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2137e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 21381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 2139e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 214050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2141d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 214250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 2143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2144e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 2145e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 214650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 214750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 2148e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 2149460a90540b045c102012da2492999557e6840526Jim Grosbach return false; 2150460a90540b045c102012da2492999557e6840526Jim Grosbach } 2151460a90540b045c102012da2492999557e6840526Jim Grosbach 2152460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 2153460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 2154460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 2155460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 2156460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 2157460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 2158460a90540b045c102012da2492999557e6840526Jim Grosbach 2159460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 2160460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 2161460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2162460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2163460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 2164460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 2165460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2166460a90540b045c102012da2492999557e6840526Jim Grosbach } 2167460a90540b045c102012da2492999557e6840526Jim Grosbach 2168460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2169460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 2170460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 2171460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2172460a90540b045c102012da2492999557e6840526Jim Grosbach } 2173460a90540b045c102012da2492999557e6840526Jim Grosbach 2174460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 2175460a90540b045c102012da2492999557e6840526Jim Grosbach 2176460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 2177460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 2178460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 217999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 218099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 218150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2184fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 2185fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 2186fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 2187fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 2188e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 2189e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 2190e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 2191e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 2192e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 2193fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 2194e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2195e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 2196e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2197e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 2198e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 2199e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 2200e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 2201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 2202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 2203e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 2204e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 2205e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 2206e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 2207e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2208e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2209e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 2210fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 2211e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2212e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 2213e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2214e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 2215e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 2216e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 2217e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 2218e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 2219e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 2220e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2221e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2222e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2223e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2224e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2225e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2226e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 222789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 222889df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 222989df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 223089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 223189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 223289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 223389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 223489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 223589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 223689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 223789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 223889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 223989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 224089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 224189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 224289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 224389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 224489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 224589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 224689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 224789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 224889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 224989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 225089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 225189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 225289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 225389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 225489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 225589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 225689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 225789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 225889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 225989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 226089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 226189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 226243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2263fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2264fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2265f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 226643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2267e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 2268e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 2269c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2270c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2271e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2272fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2273e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 2274f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2275e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2276e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 2277fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2278f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2279fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 2280fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 228143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2282fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2283fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2284f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 228543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2286fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2287fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2288c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2289c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2290fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2291fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2292fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 2293f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2294fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2295fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2296fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2297f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2298e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2299e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 23009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 23019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}' 23029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 23039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc S = Parser.getTok().getLoc(); 23059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 23069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // If this isn't a '{', this isn't a coprocessor immediate operand. 23079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 23089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_NoMatch; 23099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '{' 23109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 23119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCExpr *Expr; 23129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 23139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (getParser().ParseExpression(Expr)) { 23149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "illegal expression"); 23159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 23169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 23179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 23189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 23199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 23209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 23219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 23229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach int Val = CE->getValue(); 23239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 23249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // Check for and consume the closing '}' 23259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 23269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 23279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc E = Parser.getTok().getLoc(); 23289b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '}' 23299b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 23309b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 23319b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_Success; 23329b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach} 23339b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 2334d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 2335d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 2336d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 2337d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 2338d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 2339d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 2340d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 2341d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2342d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 2343d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 2344d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 2345d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2346d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2347d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2348d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2349d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2350d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2351d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2352d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2353d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2354d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 2355d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2356ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register. 2357ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) { 2358ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach switch (QReg) { 2359ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach default: llvm_unreachable("expected a Q register!"); 2360ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q0: return ARM::D0; 2361ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q1: return ARM::D2; 2362ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q2: return ARM::D4; 2363ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q3: return ARM::D6; 2364ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q4: return ARM::D8; 2365ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q5: return ARM::D10; 2366ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q6: return ARM::D12; 2367ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q7: return ARM::D14; 2368ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q8: return ARM::D16; 236925e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach case ARM::Q9: return ARM::D18; 2370ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q10: return ARM::D20; 2371ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q11: return ARM::D22; 2372ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q12: return ARM::D24; 2373ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q13: return ARM::D26; 2374ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q14: return ARM::D28; 2375ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach case ARM::Q15: return ARM::D30; 2376ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 2377ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach} 2378ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach 2379d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 238050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 23811355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 238218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 2383a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 2384e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 2385d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 2386d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 238716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2388d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 2389d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 2390d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 2391d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 2392d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 2393d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2394ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 2395ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // space for that many. 2396ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2397ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach 2398ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2399ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2400ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Reg = getDRegFromQReg(Reg); 2401ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2402ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach ++Reg; 2403ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 24041a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCRegisterClass *RC; 2405d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2406d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2407d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2408d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2409d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2410d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2411d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 2412d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2413e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 2414ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Store the register. 2415d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2416d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2417d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 2418d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 2419d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 2420d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2421d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2422d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2423d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2424d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2425d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 2426d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2427d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2428ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2429ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 2430ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach EndReg = getDRegFromQReg(EndReg) + 1; 2431d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2432d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2433d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2434d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2435d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2436d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2437d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2438d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2439d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2440d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2441d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2442d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2443d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2444d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2445d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2446d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2447d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2448d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2449d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2450d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2451d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2452d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2453d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 24542d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2455ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach // Allow Q regs and just interpret them as the two D sub-registers. 2456ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach bool isQReg = false; 2457ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2458ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Reg = getDRegFromQReg(Reg); 2459ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach isQReg = true; 2460ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach } 2461d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2462d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2463d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2464d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2465d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg)) 2466d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2467d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2468d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2469d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2470d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2471d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2472d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2473d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2474ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach if (isQReg) 2475ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc)); 2476d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2477d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2478d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2479d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2480d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2481d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2482e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 248350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 248450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2485d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2486d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 2487862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list 2488862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2489862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 24905c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach SMLoc S = Parser.getTok().getLoc(); 24915c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // As an extension (to match gas), support a plain D register or Q register 24925c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // (without encosing curly braces) as a single or double entry list, 24935c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach // respectively. 24945c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) { 24955c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach int Reg = tryParseRegister(); 24965c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Reg == -1) 24975c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_NoMatch; 24985c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 24995c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) { 25005c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, S, E)); 25015c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_Success; 25025c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 25035c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 25045c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Reg = getDRegFromQReg(Reg); 25055c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, S, E)); 25065c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_Success; 25075c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 25085c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach Error(S, "vector register expected"); 25095c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach return MatchOperand_ParseFail; 25105c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach } 25115c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach 25125c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 2513862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_NoMatch; 2514862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2515862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '{' token. 2516862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 2517862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2518862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int Reg = tryParseRegister(); 2519862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2520862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2521862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2522862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2523862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count = 1; 2524c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach unsigned FirstReg = Reg; 2525c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // The list is of D registers, but we also allow Q regs and just interpret 2526c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // them as the two D sub-registers. 2527c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2528c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach FirstReg = Reg = getDRegFromQReg(Reg); 2529c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Reg; 2530c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Count; 2531c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 2532c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach 2533862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach while (Parser.getTok().is(AsmToken::Comma)) { 2534862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat the comma. 2535862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach RegLoc = Parser.getTok().getLoc(); 2536862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int OldReg = Reg; 2537862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Reg = tryParseRegister(); 2538862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2539862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2540862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2541862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2542c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // vector register lists must be contiguous. 2543862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // It's OK to use the enumeration values directly here rather, as the 2544862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // VFP register classes have the enum sorted properly. 2545c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // 2546c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // The list is of D registers, but we also allow Q regs and just interpret 2547c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // them as the two D sub-registers. 2548c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 2549c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Reg = getDRegFromQReg(Reg); 2550c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach if (Reg != OldReg + 1) { 2551c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Error(RegLoc, "non-contiguous register range"); 2552c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach return MatchOperand_ParseFail; 2553c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 2554c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach ++Reg; 2555c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach Count += 2; 2556c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach continue; 2557c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach } 2558c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach // Normal D register. Just check that it's contiguous and keep going. 2559862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg != OldReg + 1) { 2560862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "non-contiguous register range"); 2561862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2562862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2563862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ++Count; 2564862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2565862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2566862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2567862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) { 2568862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(E, "'}' expected"); 2569862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2570862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2571862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '}' token. 2572862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2573862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E)); 2574862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_Success; 2575862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach} 2576862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 257743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2578f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 257943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2580706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2581706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2582706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2583706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 2584706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2585706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2586706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 2587706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 2588032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 2589706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 2590032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 2591706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 2592706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 2593032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 2594706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 2595032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 2596706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 2597706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 2598706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 2599706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2600706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 2601f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2602706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2603706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2604706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2605f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2606706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 2607706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 260843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2609a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 261043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2611a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2612a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2613a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2614a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 2615a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 26162dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // An iflags string of "none" is interpreted to mean that none of the AIF 26172dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // bits are set. Not a terribly useful instruction, but a valid encoding. 2618a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 26192dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (IFlagsStr != "none") { 26202dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 26212dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 26222dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("a", ARM_PROC::A) 26232dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("i", ARM_PROC::I) 26242dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("f", ARM_PROC::F) 26252dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Default(~0U); 26262dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 26272dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // If some specific iflag is already set, it means that some letter is 26282dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // present more than once, this is not acceptable. 26292dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (Flag == ~0U || (IFlags & Flag)) 26302dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson return MatchOperand_NoMatch; 26312dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 26322dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson IFlags |= Flag; 26332dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson } 2634a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2635a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2636a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2637a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2638a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 2639584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 2640584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 264143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2642584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 264343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2644584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2645584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2646584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2647584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 2648584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2649acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 2650acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 2651acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2652acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 2653acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 2654acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 2655acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 2656acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 2657acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 2658acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 2659acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 2660acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 2661acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 2662acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 2663acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 2664acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 2665acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 2666acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 2667acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2668acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 2669acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2670acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2671acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 2672acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 2673acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2674acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2675acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 2676acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2677acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 2678acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 2679acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2680584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 2681584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 2682584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 2683590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string SpecReg = Mask.slice(Start, Next).lower(); 2684584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 2685584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 2686584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2687584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 2688584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 2689584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2690584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 2691584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2692584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 2693584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 2694b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 2695584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 2696584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 2697584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2698584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 26994b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 2700584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 2701584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2702584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 2703bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 27044b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 2705584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 270656926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 270756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 2708584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 2709584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 2710584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 2711584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 2712584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 2713584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 2714584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2715584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2716584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 2717584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 2718584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 2719584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2720584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 2721584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2722584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 2723584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2724584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 27257784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // Special register without flags is NOT equivalent to "fc" flags. 27267784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // NOTE: This is a divergence from gas' behavior. Uncommenting the following 27277784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // two lines would enable gas compatibility at the expense of breaking 27287784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // round-tripping. 27297784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // 27307784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // if (!FlagsVal) 27317784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // FlagsVal = 0x9; 2732584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2733584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2734584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 2735584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 2736584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2737584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2738584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2739584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 2740a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 2741a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2742f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2743f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 2744f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 2745f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2746f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2747f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2748f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2749f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2750f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 2751590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string LowerOp = Op.lower(); 2752590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer std::string UpperOp = Op.upper(); 2753f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 2754f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2755f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2756f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2757f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 2758f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2759f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 2760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2761f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 2765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2766f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 2767f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 2768f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2769f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 2770f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2771f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2772f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2773f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 2774f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 2775f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2776f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2777f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 2778f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 2779f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 2780f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2781f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2782f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2783f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 2784f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2785f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 2786f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 2787f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2788c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2789c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2790c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2791c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 2792c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2793c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2794c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2795c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2796c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 2797c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 2798c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 2799c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 2800c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 2801c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2802c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 2803c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2804c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2805c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2806c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 2807c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 2808c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 2809c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 2810c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 2811c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2812580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 2813580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 2814580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 2815580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 2816580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 2817580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2818580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2819580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 2820580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 2821580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2822580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2823580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2824580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2825580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 2826580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 2827580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 2828580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 2829580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 2830580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 2831580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 2832580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2833580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2834580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2835580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 2836580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2837580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 2838580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2839580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2840580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2841580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2842580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 2843580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2844580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 2845580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2846580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2847580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 2848580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2849580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2850580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2851580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 2852580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 2853580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2854580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2855580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2856580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 2857580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 2858580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2859580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 2860580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 2861580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2862580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 28630afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 28640afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 28650afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 28660afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 28670afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 2868580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 2869580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 2870580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2871580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 2872580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 2873580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2874580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2875580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2876580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2877580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 2878580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 2879580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2880580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 2881580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 2882580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 28837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 28847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 28857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 28867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 28877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 28897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 2890326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2891326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 28927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 2893326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 2894326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 28957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 28967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 28977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 28987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 28997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 29007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 29017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 29027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 29037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 29047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 29057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 29067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 29077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 29087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 29097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 29107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 29117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 29127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 29137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 29147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 29157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 29167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 29177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 29187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 29197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 29207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 29217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 29227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 29237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 29247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 29257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 29267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 29277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 29287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 29297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 29307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2931293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2932293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2933293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2934293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2935293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2936293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2937293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2938293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2939293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2940293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2941293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2942293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2943293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2944293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2945293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2946293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2947293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2948293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2949293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2950293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2951293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2952293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2953293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2954293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2955293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2956293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2957293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2958293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2959293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2960293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2961293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2962293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2963293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2964293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2965293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2966293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2967293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2968293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2969293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2970293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2971293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2972293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2973293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2974293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2975293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2976293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2977293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2978293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2979293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2980293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2981293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2982293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2983293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2984293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2985293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2986293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2987293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2988293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2989293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2990293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2991293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2992293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2993293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2994293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2995293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2996293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 29977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 29987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 29997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 3000f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 3001f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 3002f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 30037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 30047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 30057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 30067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 30077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 30087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 30097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 301016578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 30117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 30127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 30137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 30147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 30157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 30167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 301716578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 30187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 30197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 30207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 30217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 30227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 30237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 30247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 30257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 30267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 30277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 30287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 30297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3030f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 3031f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 30320d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 30330d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 30340d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 30350d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 30360d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 3037f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 3038f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 3039f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 30407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 30417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 30427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 30437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3044251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3045251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3046251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 3047251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 3048251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 3049251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 3050251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 3051251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 3052251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 3053251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3054251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 3055251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 3056251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 3057251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 3058251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 3059251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3060251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 3061251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 3062251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 3063251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 3064251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 3065251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 3066251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 3067251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 3068251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3069251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 3070251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 3071251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 3072251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3073251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3074251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 3075251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 3076251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 3077251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 3078251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 3079251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3080251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 3081251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 3082251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3083251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3084251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3085251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3086251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3087251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 3088251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 3089251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 3090251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 3091251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 3092251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 3093251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 3094251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 3095251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 3096251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 3097251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3098251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 3099251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 3100251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 3101251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 3102251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 3103251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 3104251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3105251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3106251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3107251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3108251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 3109251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 3110251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3111251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3112251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 3113251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3114a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 3115a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3116a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3117a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3118a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 3119a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3120a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3121a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3122a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3123a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3124a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3125a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3126a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3127a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3128a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3129a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3130a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3131a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3132a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 3133a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3134a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3135a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3136a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 3137a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3138a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3139a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3140a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3141a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3142a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3143a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3144a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3145a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3146a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3147a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3148a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3149a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3150eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3151eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3152eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3153eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 3154eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3155eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3156eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3157eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3158eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 3159eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3160eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3161eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3162eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3163eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 3164eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 3165eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3166ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3167ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3168ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3169ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 3170ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3171ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3172ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 3173ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3174ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3175ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3176ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3177ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 3178ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 3179ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 31801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3181ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3182ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3183ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 31841355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3185ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3186ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3187ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 3188ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3189ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3190ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 31917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3192ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3193ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3194ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3195ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 31969ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 31979ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 31989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 31999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 32009ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 32019ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32029ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 32039ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 32049ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 32059ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 32069ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 32079ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 32089ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 32099ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 32109ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 32119ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 32129ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 3213548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 3214548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3215548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3216548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 3217548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 3218548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3219548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 3220548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3221548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3222548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 3223548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3224548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 3225548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 3226548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 32271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3228ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3229ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3230ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 32311355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3232ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3233ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3234ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3235548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3236548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3237548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 32387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 32397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 32407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 32417b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 32427b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 32437b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 32447b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 32457b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 32467b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32477b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 32487b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 32497b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 32507b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 32517b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 32527b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 32537b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 32547b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 32557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 32567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 32577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 32587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 32597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 32607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3262ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 32637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 32647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 32657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 32667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 32677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 32687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 32697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3270ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3271ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3272ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3273ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 32747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 3275ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3276ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3277ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 32787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 32797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3281aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3282ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3283ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 32847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 32857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 32867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 32877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 32887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 32897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 32907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 32917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 3292aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 32937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 32947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 32957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 32967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 32977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 32987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 33007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 33017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 33027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 33037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 33047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 33057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 33067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 33077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3308ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3309ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3310ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3311ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 33127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 3313ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3314ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3315ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 33167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 33177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3318ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3319ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 33207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3321ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 33227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 33237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 33247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 33257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 33267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3327ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3328ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3329ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3330ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 33312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 33322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 33332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 33342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 33352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 33362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 33372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 33382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 33392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 33402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 33412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 33422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 33432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 33442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 33452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 33462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 33472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 33482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 334914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 335014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 335114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 335214605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 335314605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 335414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 335514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 335614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 335714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 335814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 335914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 336014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 336114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 336214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 336314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 336414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 336514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 336614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 3367623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 3368623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3369623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3370623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 3371623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 3372623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3373623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3374623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 3375623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3376623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 3377623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3378623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 3379623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 3380623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 338188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 338288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 338388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 338488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 338588ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 338688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 338788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 338888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 338988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 33907a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 33917a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 33927a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 33937a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 339488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 33957a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 339688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 339788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 339888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 339988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 34001b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach // If we have a three-operand form, make sure to set Rn to be the operand 34011b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach // that isn't the same as Rd. 34021b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach unsigned RegOp = 4; 34031b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach if (Operands.size() == 6 && 34041b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[4])->getReg() == 34051b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[3])->getReg()) 34061b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach RegOp = 5; 34071b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1); 34081b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach Inst.addOperand(Inst.getOperand(0)); 340988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 341088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 341188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 341288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 3413623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 341412431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser:: 341512431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode, 341612431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 341712431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vd 341812431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[3])->addVecListTwoDOperands(Inst, 1); 341912431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Create a writeback register dummy placeholder. 342012431329d617064d6e72dd040a58c1635cc261abJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 342112431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vn 342212431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 342312431329d617064d6e72dd040a58c1635cc261abJim Grosbach // pred 342412431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 342512431329d617064d6e72dd040a58c1635cc261abJim Grosbach return true; 342612431329d617064d6e72dd040a58c1635cc261abJim Grosbach} 342712431329d617064d6e72dd040a58c1635cc261abJim Grosbach 342812431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser:: 342912431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode, 343012431329d617064d6e72dd040a58c1635cc261abJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 343112431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vd 343212431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[3])->addVecListTwoDOperands(Inst, 1); 343312431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Create a writeback register dummy placeholder. 343412431329d617064d6e72dd040a58c1635cc261abJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 343512431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vn 343612431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 343712431329d617064d6e72dd040a58c1635cc261abJim Grosbach // Vm 343812431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 343912431329d617064d6e72dd040a58c1635cc261abJim Grosbach // pred 344012431329d617064d6e72dd040a58c1635cc261abJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 344112431329d617064d6e72dd040a58c1635cc261abJim Grosbach return true; 344212431329d617064d6e72dd040a58c1635cc261abJim Grosbach} 344312431329d617064d6e72dd040a58c1635cc261abJim Grosbach 34444334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser:: 34454334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode, 34464334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 34474334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Create a writeback register dummy placeholder. 34484334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 34494334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vn 34504334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 34514334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vt 34524334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[3])->addVecListTwoDOperands(Inst, 1); 34534334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // pred 34544334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 34554334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach return true; 34564334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach} 34574334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach 34584334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser:: 34594334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode, 34604334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 34614334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Create a writeback register dummy placeholder. 34624334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 34634334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vn 34644334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); 34654334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vm 34664334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 34674334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // Vt 34684334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[3])->addVecListTwoDOperands(Inst, 1); 34694334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach // pred 34704334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 34714334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach return true; 34724334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach} 34734334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach 3474e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 34759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 347650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 34777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 347918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3480a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 3481762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3482b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 3483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 348418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 34851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 34867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 34877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 3488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 34890571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 34900571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 34910571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 34927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 34930571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 34947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 3495762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 3496b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 3497a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 34987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 349957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 0, 0, false, S, E)); 350003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 3501fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3502fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 3503fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3504fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3505fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 3506fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 3507fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 35087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 35097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 351050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 35117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 35127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 351350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 351457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a ':', it's an alignment specifier. 351557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Colon)) { 351657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the ':'. 351757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 351857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 351957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCExpr *Expr; 352057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (getParser().ParseExpression(Expr)) 352157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return true; 352257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 352357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // The expression has to be a constant. Memory references with relocations 352457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // don't come through here, as they use the <label> forms of the relevant 352557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // instructions. 352657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 352757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!CE) 352857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error (E, "constant expression expected"); 352957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 353057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Align = 0; 353157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach switch (CE->getValue()) { 353257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach default: 353357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "alignment specifier must be 64, 128, or 256 bits"); 353457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 64: Align = 8; break; 353557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 128: Align = 16; break; 353657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 256: Align = 32; break; 353757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 353857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 353957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Now we should have the closing ']' 354057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 354157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 354257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "']' expected"); 354357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat right bracket token. 354457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 354557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Don't worry about range checking the value here. That's handled by 354657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // the is*() predicates. 354757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 354857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, Align, 354957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 355057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 355157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 355257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // operand. 355357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 355457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 355557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the '!'. 355657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 355757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 355857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return false; 355957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 356057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 356157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a '#', it's an immediate offset, else assume it's a register 35626cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach // offset. Be friendly and also accept a plain integer (without a leading 35636cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach // hash) for gas compatibility. 35646cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach if (Parser.getTok().is(AsmToken::Hash) || 35656cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach Parser.getTok().is(AsmToken::Integer)) { 35666cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) 35676cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach Parser.Lex(); // Eat the '#'. 35687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 356950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 35700da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 35717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 35727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 35737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 357405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 35757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 35767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 35777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 35787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 35797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 35807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 35817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 35820da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 35830da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 35840da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 35850da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 35860da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 35877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 35887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 35897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 35907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 35917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 359205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 35937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 35947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 35957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 359657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, 0, 359757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 3598a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 35997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 36007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 36017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 36027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 36037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 3604762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 36057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 36067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 36079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 3608d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 36097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 36107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 36117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 36127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 36137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 36147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 36157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 36167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 36177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 36189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 36197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 36207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 36217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 36227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 36237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 36247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 36257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 36260d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 36277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 36287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 36290d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 36307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 36319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 363216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 36337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 36347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 36357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 36367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 36377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 36387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 36397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 364057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ShiftType, ShiftImm, 0, isNegative, 36417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 36427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3643f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3644f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 3645f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3646f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3647f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 3648f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 36499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 36509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 36519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 36529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 36537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 3654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 3655a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 36567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 36577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 36587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 36597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 366018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3661a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3662a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 366338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 3664a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 36650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 3666a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 36670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 3668a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 36690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 3670a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 36710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 3672a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 36730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 3674a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 36757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 3676b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 3677a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 36787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 36797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 36807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 36817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 36827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 36837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 36847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 36857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 36867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 36879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 36887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 36897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 36907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 36917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 36927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 36937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 36947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 36957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 36967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 36977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 36987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 36997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 37007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 37017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 37027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 37037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 3704a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3705a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 3706a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3707a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 37089d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 37099d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 37109d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 37119d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 37129d39036f62674606565217a10db28171b9594bc7Jim Grosbach 37139d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) 37149d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 37150e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 37160e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Disambiguate the VMOV forms that can accept an FP immediate. 37170e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <sreg>, #imm 37180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f64 <dreg>, #imm 37190e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <dreg>, #imm @ vector f32x2 37200e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <qreg>, #imm @ vector f32x4 37210e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // 37220e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // There are also the NEON VMOV instructions which expect an 37230e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // integer constant. Make sure we don't try to parse an FPImm 37240e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // for these: 37250e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.i{8|16|32|64} <dreg|qreg>, #imm 37260e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]); 37270e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!TyOp->isToken() || (TyOp->getToken() != ".f32" && 37280e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach TyOp->getToken() != ".f64")) 37290e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return MatchOperand_NoMatch; 37300e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 37319d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 37329d39036f62674606565217a10db28171b9594bc7Jim Grosbach 37339d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 37349d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 37359d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 37369d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 37379d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 37389d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 37399d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 37409d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 37419d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 37429d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 37439d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 37449d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 37459d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 37469d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 37479d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 37489d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 37499d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 37509d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 37519d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 37529d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 37539d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 37549d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 37559d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 37569d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 37579d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 37589d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 37599d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 37609d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 37619d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 37629d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 37639d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 37649d39036f62674606565217a10db28171b9594bc7Jim Grosbach 37659d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 37669d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 37679d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 37689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 37699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 37701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3771fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 3772762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 3773fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3774fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 3775fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 3776f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 3777f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 3778fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 3779f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 3780f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 3781f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 3782f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 3783f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 3784fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3785a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 3786146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 3787146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 378850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 378919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 37905cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 37911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 379250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 37930d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 379419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 37950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 379619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 379719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 37985cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 37995cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 38005cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 38015cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 38025cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 38035cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 3804e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 3805e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 3806e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 380719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 3808758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach case AsmToken::LParen: // parenthesized expressions like (_strcmp-4) 380967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 38106284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach case AsmToken::String: // quoted label names. 381167b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 3812515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 3813515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 3814515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 3815762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3816515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 381750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 3818762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 381950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 382050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 382150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 3822a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 38231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 3824d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 38251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 382663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 3827079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 3828079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 3829762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3830b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 383163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 3832515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 3833515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 383450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 383563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 3836ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach if (CE) { 3837ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach int32_t Val = CE->getValue(); 3838ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach if (isNegative && Val == 0) 3839ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 384063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 3841762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 384250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 384350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 384463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 38459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 38469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 38477597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 38487597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 38497597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 38501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 38519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 38529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 38537597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 38547597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 38559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 38569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 38577597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 38587597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 38599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 38607597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 38619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 38629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 3863a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3864a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3865a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 38661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 38677597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 38681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 38697597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 38709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 38719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 38728a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 38739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 38749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 38759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 38769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 38779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 38789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 38799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 38809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 38819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 38827597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 38839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 38847597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 38859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 38869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 38879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 38889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 38899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 38909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 38919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 38929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 38939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 38949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 38959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 38969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 38979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 38989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 3899352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 3900352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 3901352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 3902badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 390389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 39041355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 39055f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 39065f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 390789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 390889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 3909352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 3910352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 3911a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 3912352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3913badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 3914352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 3915352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 39165f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 39175f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 39185f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 39195f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 39205f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 39215f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 39225f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 39235f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 3924352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3925badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 39263f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 39273f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 3928ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 392971725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 393004d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 39312f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 39323f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 39333f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 39343f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 39353f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 39363f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 39373f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 39383f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 39393f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 39403f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 39413f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 39423f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 39433f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 39443f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 39453f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 39463f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 39473f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 39483f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 39493f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 39503f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 39513f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 39523f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 39533f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 39543f00e317064560ad11168d22030416d853829f6eJim Grosbach } 395552925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 3956345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3957352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 3958352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 3959352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 396000f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 39615f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 39625f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 39635f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 3964e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 3965e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 3966352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 3967352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 3968352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 3969352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3970a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 3971a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 3972a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 3973a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 3974a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 3975a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 3976a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 3977a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 3978a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 3979a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 3980a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 3981a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 3982a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3983a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3984a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 398589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 398689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 398789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 398889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 398989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 399089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3991352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3992352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 39933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 39943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 39953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 39963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 39973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 3998fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 39991355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 4000fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 4001eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 4002eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 40033443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 4004eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 4005d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 4006eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 4007d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 40083443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 4009d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 4010d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 4011eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 4012fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 4013eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 40143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 4015eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 4016eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 4017eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 4018eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 4019ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 4020ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 40210780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 40222bd0118472de352745a2e038245fab4974f7c87eJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" || 40232bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "ldc2" || Mnemonic == "ldc2l" || 40242bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) || 40254af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 40264af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 40271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 40283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 4029fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 40303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 4031fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 4032fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 4033fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 403463b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 4035fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 4036fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 4037badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 4038badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 4039d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 4040d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 404120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 404220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 4043d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 4044d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 4045d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 4046d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 4047d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 4048d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 4049d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 4050d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 4051d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 40528adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 4053d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 4054d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 4055d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 4056d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 40573912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 40583912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 40593912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 40603912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 40613912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 40623912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 40633912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 40643912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 406572f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 406620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 406720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 406820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 4069f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 4070f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 4071f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 407272f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 407372f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 407472f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 407520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 407620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 407720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 407872f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 4079f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 4080f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 408120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 408220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 408320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 4084f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 4085f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 408620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 408720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 408820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 408920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 409020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 409120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 409220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 409320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 409420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 409520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 409620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 409720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 409820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 409920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 410020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 410164944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 410220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 410320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 410420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 410520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 410620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 410720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 410820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 410920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 411020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 411164944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 411264944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 411364944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 411464944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 411564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 411664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 411764944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 411864944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 411964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 412064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 412164944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 412264944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 412364944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 412464944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 41251de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) || 412664944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 412764944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 412864944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 412964944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 413064944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 413164944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 413264944f48a1164c02c15ca423a53919682a89074cJim Grosbach 41337f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // Also check the 'mul' syntax variant that doesn't specify an explicit 41347f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // destination register. 41357f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 && 41367f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 41377f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 41387f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 41397f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // If the registers aren't low regs or the cc_out operand is zero 41407f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 41417f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach // remove the cc_out operand. 41427f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 41437f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 41447f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach !inITBlock())) 41457f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach return true; 41467f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach 414764944f48a1164c02c15ca423a53919682a89074cJim Grosbach 414820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 4149f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 4150f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 4151f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 4152f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 4153f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 4154f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 4155f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 415672f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 415772f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 415872f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 415972f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 41603912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 4161d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 4162d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 4163d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 41647aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) { 41657aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" || 41667aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" || 41677aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" || 41687aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" || 41697aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" || 41707aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach Tok == ".f" || Tok == ".d"; 41717aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach} 41727aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 41737aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class 41747aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be 41757aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now. 41767aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) { 41777aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm"); 41787aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach} 41797aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 4180badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 4181badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 4182badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4183badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 4184badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 4185ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 4186badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 4187352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 4188352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 4189a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 4190352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 419189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 41921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 419389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 4194badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 41950c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 41960c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 41970c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 41980c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 41990c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 42000c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 4201ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 4202ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 420389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 420489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 420589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 420689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 420789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 420889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 4209f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 4210f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 4211f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 4212f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 4213f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 421489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 421589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 421689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 421789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 421889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 4219f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 422089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 422189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 422289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 422389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 422489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4225f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 422689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 422789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4228ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 4229ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 42309717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 42313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 42323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 42333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 42343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 42353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 42363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 42373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 42383771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 42391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 42403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 424133c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 424233c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 424333c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 424433c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 4245ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 424633c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 424733c16a27370939de39679245c3dff72383c210bdJim Grosbach } 4248c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 4249c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 4250c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 4251c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 4252c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 4253c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 4254c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 425533c16a27370939de39679245c3dff72383c210bdJim Grosbach 42563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 4257f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 4258f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 42593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 4260f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 4261f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 42623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 42633771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 42643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 4265f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 4266f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 42673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 4268f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 4269badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 4270345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4271a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 4272a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 4273a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 4274a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 4275a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 4276a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4277a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 4278345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 42795747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 42805747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 42815747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 4282a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 4283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 42847aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach // Some NEON instructions have an optional datatype suffix that is 42857aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach // completely ignored. Check for that. 42867aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach if (isDataTypeToken(ExtraToken) && 42877aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken)) 42887aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach continue; 42897aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach 429081d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 429181d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 429281d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 429381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 42945747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 42955747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 42965747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 42975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 4298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 42991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4300cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4301cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4302cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 4305b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 4306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 43081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4309cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4310cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4311cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 431416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4315cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 4316186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach SMLoc Loc = getLexer().getLoc(); 4317cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4318186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach return Error(Loc, "unexpected token in argument list"); 4319cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4320146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 432134e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 4322ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4323d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 4324d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 4325d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 432620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 432720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 432820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 432920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 433020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 4331ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4332ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 4333ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 4334ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 4335ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4336cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 4337cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 4338cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 433921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // a k_CondCode operand in the list. If we're trying to match the label 434021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // version, remove the k_CondCode operand here. 4341cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 4342cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 4343cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4344cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 4345cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 4346cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 4347857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 4348857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 4349857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 4350857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 4351857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 4352857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 4353857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4354857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4355857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4356857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 4357857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 4358857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 435968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 436068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 436168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 436268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 436368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 436468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 436568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 436668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 436768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 436868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 436968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4370857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 4371857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4372857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4373934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 4374934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 4375934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 4376934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4377934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4378934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4379934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 4380934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 4381934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4382934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 4383934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4384934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4385934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 43869898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 4387ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4388ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4389189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 4390aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 4391aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 4392aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 4393aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 4394aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 4395aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 4396aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 4397aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 4398aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 4399aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 4400aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 4401aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 4402aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 4403aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 4404aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 4405aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 4406aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 4407aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 440876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 440976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 441076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 441176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 441276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 441376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 441476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 441576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 441676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 441776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 441876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 4419f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 4420f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 4421f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 4422f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 44231a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[]; 4424f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 44251a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) { 4426f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 4427f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 4428f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4429189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 4430189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 4431189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 4432189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 44331a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 4434f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 4435f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 4436b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 4437b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 4438b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 4439b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 4440f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 4441f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 4442f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 4443f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 4444a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 4445f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 4446f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 4447f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 4448f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 4449f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 4450f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 4451f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 4452f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 4453f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 4454f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 4455f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 4456f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 4457f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 4458f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 4459f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 4460f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 4461f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 4462c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 4463f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 4464f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 446551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 446651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 4467f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 4468f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4469189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 44702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 44712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 44722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 4473189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 4474189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4475189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 4476189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4477189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 4478189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 4479189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 4480189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4481189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 448214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 448314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 448414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 448514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 448614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 448714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 448814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 448914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 449014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 449153642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 449253642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 4493189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 4494189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4495189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4496189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 4497189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 449814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 4499189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 4500189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4501189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4502fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 4503fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 4504fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 4505fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 4506fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 4507fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 4508fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 4509fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 451000c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 4511fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 451293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 451376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 451476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 451576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 451676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 451776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 451893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 451993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 452093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 45217260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 45227260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 45237260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 4524aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 452576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 4526aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 4527aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 452893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 452976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 453093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 453193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 453276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 453376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 4534aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 45357260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 45367260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 45377260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 453893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 453993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 454093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 454176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 454276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 454376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 454476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 454576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 454676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 454776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 45485402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2, 45495402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // so only issue a diagnostic for thumb1. The instructions will be 45505402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // switched to the t2 encodings in processInstruction() if necessary. 45516dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 4552aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 45535402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) && 45545402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach !isThumbTwo()) 4555aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4556aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 45576dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 45586dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 45596dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 4560aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 45615402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) && 45625402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach !isThumbTwo()) 4563aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4564aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 45656dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 45666dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 45671e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 45681e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 45698213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 45701e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 45711e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 45721e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 45731e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 4574189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4575189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4576189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4577189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 4578189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 457983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser:: 4580f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 4581f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4582f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 458371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach // Handle the MOV complex aliases. 4584ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::ASRi: 4585ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSRi: 4586ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSLi: 4587ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::RORi: { 4588ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 4589ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Amt = Inst.getOperand(2).getImm(); 4590ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach switch(Inst.getOpcode()) { 4591ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach default: llvm_unreachable("unexpected opcode!"); 4592ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::ASRi: ShiftTy = ARM_AM::asr; break; 4593ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSRi: ShiftTy = ARM_AM::lsr; break; 4594ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::LSLi: ShiftTy = ARM_AM::lsl; break; 4595ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach case ARM::RORi: ShiftTy = ARM_AM::ror; break; 4596ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach } 4597ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach // A shift by zero is a plain MOVr, not a MOVsi. 4598ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi; 4599ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt); 460071810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach MCInst TmpInst; 4601ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach TmpInst.setOpcode(Opc); 460271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rd 460371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 4604ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach if (Opc == ARM::MOVsi) 4605ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 460671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); // CondCode 460771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 460871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach TmpInst.addOperand(Inst.getOperand(5)); // cc_out 460971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach Inst = TmpInst; 461083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 461171810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach } 46120352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach case ARM::t2LDMIA_UPD: { 46130352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // If this is a load of a single register, then we should use 46140352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 46150352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach if (Inst.getNumOperands() != 5) 46160352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return false; 46170352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach MCInst TmpInst; 46180352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.setOpcode(ARM::t2LDR_POST); 46190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 46200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 46210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 46220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 46230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 46240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 46250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach Inst = TmpInst; 46260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return true; 46270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach } 46280352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach case ARM::t2STMDB_UPD: { 46290352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // If this is a store of a single register, then we should use 46300352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 46310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach if (Inst.getNumOperands() != 5) 46320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return false; 46330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach MCInst TmpInst; 46340352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.setOpcode(ARM::t2STR_PRE); 46350352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 46360352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 46370352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 46380352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 46390352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 46400352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 46410352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach Inst = TmpInst; 46420352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach return true; 46430352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach } 4644f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 4645f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 4646f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 4647f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 4648f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 4649f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 4650f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 4651f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4652f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4653f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 4654f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 4655f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 4656f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4657f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4658f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 465983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 4660f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4661f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 4662f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 4663f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 4664f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 4665f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 4666f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 4667f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 4668f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 4669f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4670f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4671f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 4672f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 4673f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4674f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4675f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 4676f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 4677f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 467889e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 46790f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 46800f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 46810f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 46820f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 468383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 468489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 468583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 468683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 468789e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 4688f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 4689f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 4690f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 4691f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 4692f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 469383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 4694f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 469583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 469683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 4697f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 469851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 469951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 470083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) { 470151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 470283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 470383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 470451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 470551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 470651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 470783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){ 470851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 470983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 471083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 471151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 4712c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 4713a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 471483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) { 4715c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 471683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 471783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 4718c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 4719395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 4720395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 472183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) { 4722395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 472383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 472483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach } 47253ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 472676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 472776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 472876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 472976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 473076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 473176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 473276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 473376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 473476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 473576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 473676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 473776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 473876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 473976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 474076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 474176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 474276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 474376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 474476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 474576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 474676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 474783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 474876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 474976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 475076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 47518213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 47528213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 47538213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 47548213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 47558213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 47568213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 47578213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 47588213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 47598213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 47608213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 476183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 47628213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 47638213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 47648213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 47655402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach case ARM::tPOP: { 47665402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach bool listContainsBase; 47675402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // If the register list contains any high registers, we need to use 47685402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 47695402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // should have generated an error in validateInstruction(). 47705402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase)) 477183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 47725402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach assert (isThumbTwo()); 47735402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.setOpcode(ARM::t2LDMIA_UPD); 47745402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Add the base register and writeback operands. 47755402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 47765402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 477783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 47785402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach } 47795402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach case ARM::tPUSH: { 47805402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach bool listContainsBase; 47815402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase)) 478283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 47835402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach assert (isThumbTwo()); 47845402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.setOpcode(ARM::t2STMDB_UPD); 47855402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach // Add the base register and writeback operands. 47865402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 47875402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 478883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 47895402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach } 47901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 47911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 47921ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 47931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 47941ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 4795c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 4796c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 4797c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 47981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 47991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 48001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 48011ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 48021ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 48031ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 48041ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 48051ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 48061ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 48071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 48081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 480983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 48101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 48111ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 48121ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 48131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 48141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 48151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 48161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 48171ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 48181ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 48191ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 48201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 48211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 48221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 48231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 48241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 48251ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 48261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 48271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 48281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 48291ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 483083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 48311ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 48321ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 48331ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 4834326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 483550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 483650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 483750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 4838326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 4839326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 4840326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4841326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4842326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 4843326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4844326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 484550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 484650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 484750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 484850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 484950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 485050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 485150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 485250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 4853326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 4854326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 4855326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 4856326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 4857326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 4858326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4859326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 4860326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 486183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return true; 4862326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 4863326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 4864326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 486589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 486689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 486789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 486889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 486989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 487089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 487189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 487289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 487389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 4874f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 4875f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 487689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 487789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 487889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 487989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 488089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 488189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 488289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 4883f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4884f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 4885f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 4886f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 4887f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 4888f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 4889f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 4890f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 489189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 489289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4893f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 489483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach return false; 4895f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 4896f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 489747a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 489847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 489947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 4900194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 49011a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer const MCInstrDesc &MCID = getInstDesc(Opc); 490247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 490347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 490447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 490547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 490647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 490747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 490847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 490947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 491047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 491147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 491247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 491347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 491447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 491547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 491647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 491747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 4918f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 4919f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 492047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 4921f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 4922f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 4923f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 492447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 4925194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 4926194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 4927194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 4928194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4929194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 4930194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 4931194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 49324ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 4933194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 4934194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 4935194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 493647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 493747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 493847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 4939fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 4940fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 4941fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4942fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 4943fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 4944fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 494519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 4946193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 4947193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 494819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 4949e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 4950189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 4951189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 4952a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 4953a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 4954a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 4955a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4956189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 4957a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 4958189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4959f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 496083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // encoding is selected. Loop on it while changes happen so the 496183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // individual transformations can chain off each other. E.g., 496283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8) 496383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach while (processInstruction(Inst, Operands)) 496483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach ; 4965f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 4966a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 4967a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 4968a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 4969a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4970a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 4971fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 4972fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 4973e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 4974e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 4975e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 4976e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 4977e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 4978e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 4979e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 4980e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 498116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4982e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 4983e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 4984e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 498516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4986e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 4987e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 4988e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 498947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 4990b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 499188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 499288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 4993f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 4994f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 499547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 499647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 4997194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 4998194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 4999194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 5000194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 5001fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 500216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5003c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 5004146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 5005fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 5006fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 50071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 5008ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 5009ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 5010ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 50111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 5012515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 50131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 5014515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 50151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 5016515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 50171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 5018515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 50191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 5020ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 5021ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 5022ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 50231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 5024ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 50251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 5026ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 5027ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 5028ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 5029ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 5030ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 5031ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5032aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 5033ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5034ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 5035ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 503616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 5037ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 5038ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 5039ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 5040b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5041ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 5042ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 5043ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 5044b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5045ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 5046ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 5047ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 50481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 5049515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 50501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 5051515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 5052515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 5053b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5054515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5055515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 5056515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 5057515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 5058515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5059515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5060515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 50611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 5062515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 50631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 50646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 50656469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 50666469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 50676469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 50686469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 50696469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 50706469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 50716469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 50726469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 50736469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 5074d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach Name = Tok.getIdentifier(); 50756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 50766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 50776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 5078d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) 5079515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 5080b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5081515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 50826469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 50836469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 5084d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach Name = Parser.getTok().getIdentifier(); 50856469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 50866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 5087642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 5088642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 5089642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 5090515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5091515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5092515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 50931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 5094515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 50951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 509618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5097515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 5098515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 509938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 510058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 5101b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 510258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 51039e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 5104515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 5105515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 5106515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5107515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 510818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 5109b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5110515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5111515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 5112515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 5113515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5114515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5115515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 51161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 5117515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 51181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 511918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5120515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 5121515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 512218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 512358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 5124b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 512558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 5126b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5127515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 5128515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 5129515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 5130515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 513118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 5132b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 5133515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 513432869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 513598447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 5136ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 513798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 513832869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 513998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 5140ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 514198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 5142eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 51432a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 5144515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 5145515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 5146515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 514790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 514890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 51499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 5150ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 515194b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 515294b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 515390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 5154ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 51553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 51560692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 51570692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 51583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 5159