ARMAsmParser.cpp revision 862019c37f5b5d76e34eeb0d5686e617d544059f
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" 330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 34345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 35c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4394b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 44ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach struct { 48f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes Cond; // Condition for IT block. 49f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Mask:4; // Condition mask for instructions. 50f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Starting at first 1 (from lsb). 51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '1' condition as indicated in IT. 52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '0' inverse of condition (else). 53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Count of instructions in IT block is 54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // 4 - trailingzeroes(mask) 55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool FirstCond; // Explicit flag for when we're parsing the 57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // First instruction in the IT block. It's 58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // implied in the mask, so needs special 59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // handling. 60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned CurPosition; // Current position in parsing of IT 62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // block. In range [0,3]. Initialized 63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // according to count of instructions in block. 64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // ~0U if no active IT block. 65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } ITState; 66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool inITBlock() { return ITState.CurPosition != ~0U;} 67a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach void forwardITPosition() { 68a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (!inITBlock()) return; 69a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Move to the next instruction in the IT block, if there is one. If not, 70a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // mark the block as done. 71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach unsigned TZ = CountTrailingZeros_32(ITState.Mask); 72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (++ITState.CurPosition == 5 - TZ) 73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach ITState.CurPosition = ~0U; // Done with the IT block after this. 74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 75f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 76f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 77ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 78ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 79ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 850d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 97515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 9989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool &CarrySetting, unsigned &ProcessorIMod, 10089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask); 1011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 102fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 10316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 104ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 105ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 106ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 107ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 108ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 109ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 110ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 11147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 11247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 11347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 114194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 115194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 116194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 117acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool hasV7Ops() const { 118acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::HasV7Ops; 119acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 12032869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 121ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 122ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 12332869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 124acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool isMClass() const { 125acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::FeatureMClass; 126acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 127ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1310692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1320692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 13689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 13743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 138f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 13943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 140f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 1419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OperandMatchResultTy parseCoprocOptionOperand( 1429b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 14343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1448bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1468bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1488bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 149f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 150f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 155f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 156f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 157c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 158580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 160293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 162251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 1639d39036f62674606565217a10db28171b9594bc7Jim Grosbach OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 164862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&); 165ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 166ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 167a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 168a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 169a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 170a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 171eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 172eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 173ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 174ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 176ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1779ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 1789ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &); 179548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 180548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 182ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1847b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 19614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 197623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 198623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 20088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 201189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 202189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 203189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 204f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach void processInstruction(MCInst &Inst, 205f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 206d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 207d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 208189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 209ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 21047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 211194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 212f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Match_RequiresNotITBlock, 213194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 214194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 21547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 21647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 217ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 21894b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 219ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 22032869205052430f45d598fba25ab878d8b29da2dEvan Cheng 221ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 222ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 223f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 224f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Not in an ITBlock to start with. 225f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = ~0U; 226ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 227ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 2291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 2301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 231189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 2321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 2331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 23447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 23547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 2361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 2371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 239ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 24016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 24116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2423a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 2433a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 246146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 247762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 24821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CondCode, 24921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CCOut, 25021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ITCondMask, 25121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocNum, 25221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocReg, 2539b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach k_CoprocOption, 25421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Immediate, 25521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_FPImmediate, 25621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MemBarrierOpt, 25721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Memory, 25821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_PostIndexRegister, 25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MSRMask, 26021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ProcIFlags, 261460a90540b045c102012da2492999557e6840526Jim Grosbach k_VectorIndex, 26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Register, 26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RegisterList, 26421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_DPRRegisterList, 26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_SPRRegisterList, 266862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach k_VectorList, 26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedRegister, 26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedImmediate, 26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShifterImmediate, 27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RotateImmediate, 27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_BitfieldDescriptor, 27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Token 273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 275762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 27624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 279a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2828462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2838462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 284fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 285fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 286fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 287fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 2889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach unsigned Val; 2899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } CoprocOption; 2909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 2919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach struct { 29289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 29389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 29489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 29589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 29689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 29789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 29889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 29989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 300a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 301a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 302a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 303a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 310a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 311a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 315a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 316862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // A vector register list is a sequential list of 1 to 4 registers. 317862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach struct { 318862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned RegNum; 319862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count; 320862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } VectorList; 321862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 3228155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 323460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned Val; 324460a90540b045c102012da2492999557e6840526Jim Grosbach } VectorIndex; 325460a90540b045c102012da2492999557e6840526Jim Grosbach 326460a90540b045c102012da2492999557e6840526Jim Grosbach struct { 327cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 328cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 32916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3309d39036f62674606565217a10db28171b9594bc7Jim Grosbach struct { 3319d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned Val; // encoded 8-bit representation 3329d39036f62674606565217a10db28171b9594bc7Jim Grosbach } FPImm; 3339d39036f62674606565217a10db28171b9594bc7Jim Grosbach 3346a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 336a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 3377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 3387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 3397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 3407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 3417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 34257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned ShiftImm; // shift for OffsetReg. 34357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment; // 0 = no alignment specified 34457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // n = alignment in bytes (8, 16, or 32) 3457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 346e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach } Memory; 3470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 3480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 3497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 350f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 351f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 352f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 3537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 3547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 356580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 357e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 358580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 359e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 360e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 361e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 362e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 363e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 364af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 36592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 36692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 36792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 36892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 369af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 3707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 3717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 373293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 374293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 375293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 376293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 37816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 379146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 380146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 381762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 382762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 383762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 384762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 385762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 38621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 3878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 38921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: 39089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 39189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 39221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 3938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 394762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 39521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 39621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 397762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 398762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 39921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 40021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 40121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: 40224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 4038d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 404862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 405862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach VectorList = o.VectorList; 406862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 40721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 40821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 409fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 410fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 4119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 4129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach CoprocOption = o.CoprocOption; 4139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 415762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 416762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 4189d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImm = o.FPImm; 4199d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 42021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 421706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 422706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 42321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 424e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory = o.Memory; 425762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 42621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 4277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 4287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 42921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 430584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 431584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 43221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: 433a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 4340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 43521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 4370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 43821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 439af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 440e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 44121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 442af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 44392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 44421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 4457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 4467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 44721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 448293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 449293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 450460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 451460a90540b045c102012da2492999557e6840526Jim Grosbach VectorIndex = o.VectorIndex; 452460a90540b045c102012da2492999557e6840526Jim Grosbach break; 453762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 454762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 45516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 456762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 457762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 458762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 459762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 46221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_CondCode && "Invalid access!"); 4638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 4648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 466fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 46721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 468fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 469fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 470fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 471a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 47221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Token && "Invalid access!"); 473a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 474a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 47721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 4787729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4815fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 48221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 48321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind == k_SPRRegisterList) && "Invalid access!"); 48424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 4858d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 4868d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 487cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 48821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Immediate && "Invalid access!"); 489cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 490cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 491cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 4929d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned getFPImm() const { 49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_FPImmediate && "Invalid access!"); 4949d39036f62674606565217a10db28171b9594bc7Jim Grosbach return FPImm.Val; 4959d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 4969d39036f62674606565217a10db28171b9594bc7Jim Grosbach 497460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned getVectorIndex() const { 498460a90540b045c102012da2492999557e6840526Jim Grosbach assert(Kind == k_VectorIndex && "Invalid access!"); 499460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val; 500460a90540b045c102012da2492999557e6840526Jim Grosbach } 501460a90540b045c102012da2492999557e6840526Jim Grosbach 502706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MemBarrierOpt && "Invalid access!"); 504706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 505706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 506706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 507a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 50821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_ProcIFlags && "Invalid access!"); 509a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 510a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 511a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 512584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 51321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MSRMask && "Invalid access!"); 514584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 515584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 516584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 51721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocNum() const { return Kind == k_CoprocNum; } 51821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocReg() const { return Kind == k_CoprocReg; } 5199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach bool isCoprocOption() const { return Kind == k_CoprocOption; } 52021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCondCode() const { return Kind == k_CondCode; } 52121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCCOut() const { return Kind == k_CCOut; } 52221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITMask() const { return Kind == k_ITCondMask; } 52321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITCondCode() const { return Kind == k_CondCode; } 52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isImm() const { return Kind == k_Immediate; } 52521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isFPImm() const { return Kind == k_FPImmediate; } 526a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isImm8s4() const { 52721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 528a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 529a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 530a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!CE) return false; 531a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Value = CE->getValue(); 532a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 533a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 53472f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 53672f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 53772f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 53872f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 53972f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 54072f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 54172f39f8436848885176943b0ba985a7171145423Jim Grosbach } 54272f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 54472f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 54572f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 54672f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 54772f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 54872f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 54972f39f8436848885176943b0ba985a7171145423Jim Grosbach } 5506b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 55121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5536b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5546b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5556b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 5576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 55883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 55921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 56083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 56183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 56283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 56383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 56483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 56583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 56683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 56721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 56883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 56983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 57083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 57183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 57283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 57383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 5747c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 57521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5767c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 5777c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5787c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 5797c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 5807c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 5817c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 582f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 58321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 584f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 585f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 586f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 587f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 588f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 589f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 5904a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 59121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5924a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 5934a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5944a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 5954a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 5964a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 5974a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 598fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 59921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 600fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 601fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 602fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 603fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 604fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 605fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 606ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 60721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 608ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 609ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 610ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 611ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 612ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 613ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 614ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 615ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 616ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 61721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 618ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 619ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 620ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 621ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 622ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 623ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 62470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 62521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 62670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 62770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 62870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 62970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 63070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 63170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 632f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 63321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 634f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 635f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 636f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 637f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 638f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 639f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 640f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 64121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 642f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 643f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 644f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 645f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 646f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 6486bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 64921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6506bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 6516bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6526bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 6536bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 6546bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 6556bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 6566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 65721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6586b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 6596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6606b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 6616b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 6626b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 6636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 664c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 66521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 666c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 667c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 668c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 669c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 670c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 671c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 67221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isReg() const { return Kind == k_Register; } 67321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegList() const { return Kind == k_RegisterList; } 67421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 67521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 67621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isToken() const { return Kind == k_Token; } 67721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 67821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemory() const { return Kind == k_Memory; } 67921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isShifterImm() const { return Kind == k_ShifterImmediate; } 68021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 68121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 68221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRotImm() const { return Kind == k_RotateImmediate; } 68321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 68421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 685f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 68621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 687f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 68857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isMemNoOffset(bool alignOK = false) const { 689f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 690ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 6917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 69257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 && 69357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach (alignOK || Memory.Alignment == 0); 69457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 69557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isAlignedMemory() const { 69657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return isMemNoOffset(true); 697ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 6987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 69957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 7007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 701e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 7027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 703e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 704e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 7057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 7067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 707039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 70821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 709039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 710039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 711039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 712039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 713039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 714039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 715039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 7162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 71757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 7182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 719e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::no_shift) return false; 7202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 721e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 7222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 723e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 724e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 7252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 7262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 72821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate && Kind != k_PostIndexRegister) 7292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 73021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) 7312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 7322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 7332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 7352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 736251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 737251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 7382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 74057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 7417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 742e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return false; 7437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 744e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 745e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 7460da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 7470da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson Val == INT32_MIN; 7487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 7497f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBB() const { 750e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 75157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 7527f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7537f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7547f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7557f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBH() const { 756e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 75757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 75857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0 ) 7597f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7607f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7617f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 76357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0) 764ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 765ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 766ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 767ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach bool isT2MemRegOffset() const { 76857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 76957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0) 770ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 771ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach // Only lsl #{0, 1, 2, 3} allowed. 772e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType == ARM_AM::no_shift) 773ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 774e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 775ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 776ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 777ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 7787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 7797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 7807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 781e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 78257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 78387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 784e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach return isARMLowRegister(Memory.BaseRegNum) && 785e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 78660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 78760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 788e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 78957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 79060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 79160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 792e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 793e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 794ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 795ecd858968384be029574d845eb098d357049e02eJim Grosbach } 79638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 797e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 79857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 79938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 80038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 801e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 802e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 80338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 80438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 80548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 806e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 80757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 80848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 80948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 810e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 811e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 81248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 81348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 814ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 81557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 81657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 817ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 818ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 819e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 820e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 821ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 822505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 823a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isMemImm8s4Offset() const { 82457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 825a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 826a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate offset a multiple of 4 in range [-1020, 1020]. 827e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 828e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 829a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 830a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 831b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach bool isMemImm0_1020s4Offset() const { 83257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 833b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return false; 834b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // Immediate offset a multiple of 4 in range [0, 1020]. 835e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 836e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 837b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 838b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 8397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 84057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 841f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 8427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 843e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 844e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8454d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson return (Val == INT32_MIN) || (Val > -256 && Val < 256); 846f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 847f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach bool isMemPosImm8Offset() const { 84857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 849f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return false; 850f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach // Immediate offset in range [0, 255]. 851e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 852e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 853f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return Val >= 0 && Val < 256; 854f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 855a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemNegImm8Offset() const { 85657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 857a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 858a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [-255, -1]. 859e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 860e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 861a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return Val > -256 && Val < 0; 862a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 863a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemUImm12Offset() const { 864a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 865a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 866a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // and we reject it. 86721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 868a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return true; 869a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 87057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 871a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 872a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [0, 4095]. 873e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 874e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 875a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return (Val >= 0 && Val < 4096); 876a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 8777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 87809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 87909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 88009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 88121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 88209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 88309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 88457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 885ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 8867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 887e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 888e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8890da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 8907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 8917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 89221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 8937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 8947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 895ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 8967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 89763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 898ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 8992bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isPostIdxImm8s4() const { 9002bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Kind != k_Immediate) 9012bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return false; 9022bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9032bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (!CE) return false; 9042bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int64_t Val = CE->getValue(); 9052bd0118472de352745a2e038245fab4974f7c87eJim Grosbach return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 9062bd0118472de352745a2e038245fab4974f7c87eJim Grosbach (Val == INT32_MIN); 9072bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 9087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 90921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMSRMask() const { return Kind == k_MSRMask; } 91021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isProcIFlags() const { return Kind == k_ProcIFlags; } 9113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9120e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // NEON operands. 913862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach bool isVecListOneD() const { 914862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Kind != k_VectorList) return false; 915862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return VectorList.Count == 1; 916862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 917862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 918460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex8() const { 919460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 920460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 8; 921460a90540b045c102012da2492999557e6840526Jim Grosbach } 922460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex16() const { 923460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 924460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 4; 925460a90540b045c102012da2492999557e6840526Jim Grosbach } 926460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex32() const { 927460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 928460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 2; 929460a90540b045c102012da2492999557e6840526Jim Grosbach } 930460a90540b045c102012da2492999557e6840526Jim Grosbach 9310e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach bool isNEONi8splat() const { 9320e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (Kind != k_Immediate) 9330e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return false; 9340e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9350e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Must be a constant. 9360e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!CE) return false; 9370e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach int64_t Value = CE->getValue(); 9380e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // i8 value splatted across 8 bytes. The immediate is just the 8 byte 9390e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // value. 9400e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return Value >= 0 && Value < 256; 9410e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 942460a90540b045c102012da2492999557e6840526Jim Grosbach 943ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach bool isNEONi16splat() const { 944ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Kind != k_Immediate) 945ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return false; 946ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 947ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // Must be a constant. 948ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (!CE) return false; 949ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach int64_t Value = CE->getValue(); 950ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // i16 value in the range [0,255] or [0x0100, 0xff00] 951ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00); 952ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 953ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 9546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32splat() const { 9556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 9566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 9576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 9596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 9606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 9616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X. 9626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 9636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 9646248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 9656248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000); 9666248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 9676248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 9686248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32vmov() const { 9696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 9706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 9716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 9736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 9746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 9756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 9766248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 9776248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 9786248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 9796248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 9806248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000) || 9816248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 9826248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 9836248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 9846248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 985f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach bool isNEONi64splat() const { 986f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (Kind != k_Immediate) 987f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return false; 988f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 989f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // Must be a constant. 990f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (!CE) return false; 991f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 992f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // i64 value with each byte being either 0 or 0xff. 993f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i) 994f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 995f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return true; 996f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 997f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 9983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 99914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 100014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 100114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 100214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 10033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 10043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 10053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 10063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 10073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 10088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1009345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 10108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 101104f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 101204f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 10138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 10148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1015fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 1016fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1017fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 1018fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1019fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 10209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 10219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(getCoproc())); 10239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 10249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 10259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 10269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val)); 10289b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 10299b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 103089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 103189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 103289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 103389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 103489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 103589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 103689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 103789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 103889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 103989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 1040d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 1041d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1042d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 1043d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1044d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 1045a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 1046a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 1047a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 1048a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1049a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1050af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 1051e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1052af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 1053af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 1054af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 1055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 1056af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 1057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1059af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 1060152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 1061af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 1062af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 106392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 1064af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 106592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 106692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1067580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 10680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 1069580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 1070580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 10710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 10720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 107387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 10747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 10755fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 10765fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 10777729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 10787729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 107987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 108087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 10810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 10820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 10830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 10840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 10850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 10860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 10870f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 10880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 10897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 10907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 10927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 10937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 10947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1095293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1096293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1097293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 1098293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 1099293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 1100293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1101293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1102293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 1103293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 1104293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1105293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 11063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 11076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 11096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 11106b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 11119d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 11129d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11139d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 11149d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 11159d39036f62674606565217a10db28171b9594bc7Jim Grosbach 1116a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1117a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1118a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 1119a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 1120a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1121a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1122a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1123a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 112472f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 112572f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 112672f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 112772f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 112872f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 112972f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 113072f39f8436848885176943b0ba985a7171145423Jim Grosbach } 113172f39f8436848885176943b0ba985a7171145423Jim Grosbach 113272f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 113372f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 113472f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 113572f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 113672f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 113772f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 113872f39f8436848885176943b0ba985a7171145423Jim Grosbach } 113972f39f8436848885176943b0ba985a7171145423Jim Grosbach 11406b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 11416b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11426b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 11436b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 11446b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 114583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 114683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 114783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 114883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 114983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 115083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 11517c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11527c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 11537c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 11547c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 11557c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 115683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 115783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 115883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 115983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 1160f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1161f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1162f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1163f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1164f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1165f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1166f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1167f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 11684a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 11694a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 11704a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 11714a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 11724a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 11744a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 11754a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 1176fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 1177fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1178fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 1179fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 1180fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 1181ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 1182ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1183ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 1184ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 1185ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 1186ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 1187ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1188ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 118970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 119070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 119170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 119270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 119370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 119470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 119570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 119670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 119770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1198ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1199ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1200f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 1201f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1202f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 1203f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1204f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1205f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1206f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1207f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1208f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1209f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1210f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1211f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1212f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1213f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 12146bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 12156bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 12166bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 12176bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 12186bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 12196b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 12203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 12213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 12223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 122316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1224c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 1225c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1226c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 1227c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1228c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1229706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1230706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1231706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1232706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1233706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 12347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 12357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1236e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1237505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1238505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 123957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 124057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 124157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 124257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 124357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 124457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 12457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 12467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1247e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1248e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 12497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 12517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 12527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 12537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 12547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 12557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 12567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 1257e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1258e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1259ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1260e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1261e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 12627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1263ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1264ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1265039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1266039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1267039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1268039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1269039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1270039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1271039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1272039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1273039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1274039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1275039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1276039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1277039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1278039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 12792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 12802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1281e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1282e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 12832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 12852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 12862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 12872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 12882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 12892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 12902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 1291e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 12922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 1293e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1294e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 12952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 12972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 12982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 12992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 130021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) { 13012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 13022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 13032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 13042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1305251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 13062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 13072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 13082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 13092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 13102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 13112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 13122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 13132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 13142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1315251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 13162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 13172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 13192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 13207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 13217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 13227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1323e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 13247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 13257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 13267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 13277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 13287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 1329e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 13307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 13327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1333a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1334a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1335e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1336e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1337a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1338a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1339a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1340b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1341b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1342b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1343e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1344e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1345b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1346b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1347b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 13487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 13497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1350e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1351e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 13527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1353ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1354ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1355f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1356f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1357f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1358f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1359a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1360f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1361a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1362a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1363a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1364a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1365a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 136621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 1367a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1368a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1369a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1370a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1371a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1372a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1373e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1374e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1375a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1376a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1377a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 13787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 13797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 138009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 138121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 138209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 138309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 138409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 138509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 138609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 138709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1388e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1389e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 13907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 139292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 13937f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 13947f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1395e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1396e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 13977f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 13987f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 13997f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 14007f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1401e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1402e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14037f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 14047f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 14057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 14067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1407e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1408e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1409e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1410e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1413d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1414ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1415ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1416e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1417e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1418e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 1419ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1420ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 14217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 14227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1423e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1424e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 142514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 14263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 142760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 142860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1429e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1430e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 143160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 143248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 143348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 143438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 143538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1436e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 1437e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 143838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 143938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 144038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 144148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 144248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1443e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 1444e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 144548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 144660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 144760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1448ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1449ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1450e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1451e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1452ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1453ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1454ecd858968384be029574d845eb098d357049e02eJim Grosbach 14557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 14567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 14577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 14597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 14607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 146163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 14627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 14637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1464f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1465ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 14662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 14672bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 14682bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14692bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(CE && "non-constant post-idx-imm8s4 operand!"); 14702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int Imm = CE->getValue(); 14712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isAdd = Imm >= 0; 14722bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Imm == INT32_MIN) Imm = 0; 14732bd0118472de352745a2e038245fab4974f7c87eJim Grosbach // Immediate is scaled by 4. 14742bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 14752bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 14762bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 14772bd0118472de352745a2e038245fab4974f7c87eJim Grosbach 14787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 14797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 14807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1481f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1482f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1483f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1484f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1485f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1486f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1487f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1488f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1489f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1490f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1491f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1492f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1493ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1494ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1495584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1496584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1497584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1498584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1499584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1500a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1501a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1502a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1503a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1504a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1505862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach void addVecListOneDOperands(MCInst &Inst, unsigned N) const { 1506862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1507862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1508862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1509862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1510460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1511460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1512460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1513460a90540b045c102012da2492999557e6840526Jim Grosbach } 1514460a90540b045c102012da2492999557e6840526Jim Grosbach 1515460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1516460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1517460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1518460a90540b045c102012da2492999557e6840526Jim Grosbach } 1519460a90540b045c102012da2492999557e6840526Jim Grosbach 1520460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1521460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1522460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1523460a90540b045c102012da2492999557e6840526Jim Grosbach } 1524460a90540b045c102012da2492999557e6840526Jim Grosbach 15250e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 15260e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 15270e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // The immediate encodes the type of constant as well as the value. 15280e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Mask in that this is an i8 splat. 15290e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 15300e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00)); 15310e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 15320e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 1533ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 1534ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1535ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // The immediate encodes the type of constant as well as the value. 1536ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1537ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach unsigned Value = CE->getValue(); 1538ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Value >= 256) 1539ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value = (Value >> 8) | 0xa00; 1540ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach else 1541ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value |= 0x800; 1542ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 1543ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1544ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 15456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 15466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 15476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 15486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 15496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 15506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xff00) 15516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | 0x200; 15526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xff0000) 15536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | 0x400; 15546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 15556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 15566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 15576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 15586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 15596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 15606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 15616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 15626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 15636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 15646248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xffff) 15656248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 15666248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xffffff) 15676248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 15686248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 15696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 15706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 15716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 15726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1573f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 1574f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1575f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // The immediate encodes the type of constant as well as the value. 1576f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1577f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1578f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach unsigned Imm = 0; 1579f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 1580f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Imm |= (Value & 1) << i; 1581f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1582f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00)); 1583f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1584f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 1585b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1586b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 158789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 158821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ITCondMask); 158989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 159089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 159189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 159289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 159389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 159489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 15953a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 159621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CondCode); 1597345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1598345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1599345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 16003a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1601345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1602345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1603fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 160421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocNum); 1605fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1606fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1607fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1608fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1609fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1610fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1611fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 161221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocReg); 1613fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1614fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1615fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1616fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1617fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1618fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 16199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) { 16209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocOption); 16219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->Cop.Val = Val; 16229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->StartLoc = S; 16239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->EndLoc = E; 16249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return Op; 16259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 16269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 1627d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 162821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CCOut); 1629d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1630d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1631d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1632d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1633d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1634d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 16353a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 163621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Token); 1637762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1638762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1639762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1640762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 16413a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1642a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1643a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 164450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 164521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Register); 1646762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1647762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1648762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 16493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1650a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1651a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1652e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1653e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1654e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1655e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1656e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 165721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1658af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1659af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1660af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1661af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1662e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1663e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1664e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1665e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1666e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 166792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 166892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 166992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 167092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 167121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1672af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1673af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1674af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 167592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 167692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 167792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 167892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 167992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1680580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 16810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 168221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1683580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1684580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 16850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 16860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 16870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 16880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 16890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 16907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 169121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_RotateImmediate); 16927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 16937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 16947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 16957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 16967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 16977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1698293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1699293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 170021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 1701293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1702293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1703293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1704293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1705293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1706293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1707293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 17087729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 17095fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1710cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 171121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach KindTy Kind = k_RegisterList; 17120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1713d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 171421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_DPRRegisterList; 1715d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1716275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 171721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_SPRRegisterList; 17180f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 17190f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 17205fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 17217729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 172224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1723cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1724cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1725cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 17268d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 17278d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 17288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 1729862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count, 1730862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc S, SMLoc E) { 1731862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorList); 1732862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.RegNum = RegNum; 1733862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.Count = Count; 1734862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->StartLoc = S; 1735862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->EndLoc = E; 1736862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return Op; 1737862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1738862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1739460a90540b045c102012da2492999557e6840526Jim Grosbach static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 1740460a90540b045c102012da2492999557e6840526Jim Grosbach MCContext &Ctx) { 1741460a90540b045c102012da2492999557e6840526Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorIndex); 1742460a90540b045c102012da2492999557e6840526Jim Grosbach Op->VectorIndex.Val = Idx; 1743460a90540b045c102012da2492999557e6840526Jim Grosbach Op->StartLoc = S; 1744460a90540b045c102012da2492999557e6840526Jim Grosbach Op->EndLoc = E; 1745460a90540b045c102012da2492999557e6840526Jim Grosbach return Op; 1746460a90540b045c102012da2492999557e6840526Jim Grosbach } 1747460a90540b045c102012da2492999557e6840526Jim Grosbach 17483a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 174921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Immediate); 1750762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1751762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1752762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 17533a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1754cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1755cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 17569d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 175721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_FPImmediate); 17589d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 17599d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 17609d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 17619d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 17629d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 17639d39036f62674606565217a10db28171b9594bc7Jim Grosbach 17647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 17657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 17667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 17677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 17680d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 176957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment, 17707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 17713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 177221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Memory); 1773e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.BaseRegNum = BaseRegNum; 1774e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetImm = OffsetImm; 1775e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetRegNum = OffsetRegNum; 1776e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftType = ShiftType; 1777e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftImm = ShiftImm; 177857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Op->Memory.Alignment = Alignment; 1779e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.isNegative = isNegative; 17807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 17817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 17827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 17837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 178416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1785f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1786f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1787f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 17887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 178921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 17907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1791f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1792f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1793f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1794762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1795762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 17963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1797a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1798706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1799706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 180021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 1801706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1802706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1803706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1804706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1805706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1806a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 180821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ProcIFlags); 1809a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1810a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1812a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1813a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1814584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1815584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 181621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MSRMask); 1817584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1818584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1819584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1820584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1821584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1822a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1823a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1824a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1825a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1826b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1827fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 182821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 18299d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 18309d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 18319d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 183221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 18336a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1834fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 183521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 1836d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1837d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 183821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: { 183989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)", 184089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)", 184189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(tee)", "(eee)" }; 184289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 184389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 184489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 184589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 184621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 1847fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1848fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 184921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 1850fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1851fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 18529b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 18539b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OS << "<coprocessor option: " << CoprocOption.Val << ">"; 18549b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 185521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 1856584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1857584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 185821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 1859fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1860fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 186121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 1862706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1863706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 186421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 18656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 1866e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach << " base:" << Memory.BaseRegNum; 18676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1868fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 186921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 1870f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1871f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1872f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1873f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1874f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1875f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 18767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 187721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: { 1878a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1879a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1880a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1881a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1882a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1883a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1884a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1885a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 188621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 188750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1888fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 188921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 1890580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1891580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1892e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 189321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 189492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1895af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1896af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1897af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1898af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1899e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 19000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 190121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 190292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1903af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1904af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1905af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 190692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 190792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 190821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 19097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 19107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 191121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 1912293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1913293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1914293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 191521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 191621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 191721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: { 19188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 19198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 19205fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 19215fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 19227729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 19237729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 19247729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 19258d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 19268d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 19278d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 19288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 19298d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1930862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 1931862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OS << "<vector_list " << VectorList.Count << " * " 1932862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach << VectorList.RegNum << ">"; 1933862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 193421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 1935fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1936fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1937460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 1938460a90540b045c102012da2492999557e6840526Jim Grosbach OS << "<vectorindex " << getVectorIndex() << ">"; 1939460a90540b045c102012da2492999557e6840526Jim Grosbach break; 1940fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1941fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 19423483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 19433483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 19443483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 19453483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 19463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 19473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 19483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 19493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 195069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 195169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 19521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1953bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1954bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1955bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1956bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 19579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1958e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1959e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 19603a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 19611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 196218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 19637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1964d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1965a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1966a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 19670c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 19680c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 19690c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 19700c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 19710c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 19720c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 19730c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 19740c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 19750c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 19760c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 19770c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 19780c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 197969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1980b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1981460a90540b045c102012da2492999557e6840526Jim Grosbach 1982460a90540b045c102012da2492999557e6840526Jim Grosbach#if 0 1983460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 1984460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 1985460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 1986460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 1987460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 1988460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 1989460a90540b045c102012da2492999557e6840526Jim Grosbach 1990460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 1991460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 1992460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1993460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 1994460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 1995460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 1996460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1997460a90540b045c102012da2492999557e6840526Jim Grosbach } 1998460a90540b045c102012da2492999557e6840526Jim Grosbach 1999460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2000460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 2001460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 2002460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2003460a90540b045c102012da2492999557e6840526Jim Grosbach } 2004460a90540b045c102012da2492999557e6840526Jim Grosbach 2005460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 2006460a90540b045c102012da2492999557e6840526Jim Grosbach 2007460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 2008460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 2009460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 2010460a90540b045c102012da2492999557e6840526Jim Grosbach } 2011460a90540b045c102012da2492999557e6840526Jim Grosbach#endif 2012460a90540b045c102012da2492999557e6840526Jim Grosbach 2013e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 2014e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 2015d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 201619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 201719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 201819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 201919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 202019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 20210d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 20220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 20230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 20240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 20250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 20260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 20270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 20280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 20290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 20300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 20310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 20320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 20330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 20340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 20350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 20360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 20370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 203819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 20390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2040e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 2041e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 2042e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 2043e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 2044e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 2045eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 2046e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 2047e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 2048e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 2049e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 2050e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 2051e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 2052e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 2053e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 2054e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 2055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 2056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 2057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 2058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2059e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 2060e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 2061e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 206219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 206319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 206419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 206519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 2067e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 206819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 206919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 207019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 207119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2072e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 2073e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 2074e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 2075e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 2076e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 2077e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 2078e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 207919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 208019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 2081e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2082e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 20831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 2084e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 208519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 208619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 208719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 208819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 208919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 209019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 2091e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 209219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 209319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2094e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2095e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 209692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 209792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 2098af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 20990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 210092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 210192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 210292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 21030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 210419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 21050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 21060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 21070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 210850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 210950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 211050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 2111e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 2112e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 2113e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 211450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 21151355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2116e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 21171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 2118e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 211950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2120d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 212150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 2122a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2123e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 2124e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 212550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 212650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 2127e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 2128460a90540b045c102012da2492999557e6840526Jim Grosbach return false; 2129460a90540b045c102012da2492999557e6840526Jim Grosbach } 2130460a90540b045c102012da2492999557e6840526Jim Grosbach 2131460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 2132460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 2133460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 2134460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 2135460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 2136460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 2137460a90540b045c102012da2492999557e6840526Jim Grosbach 2138460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 2139460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 2140460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2141460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2142460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 2143460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 2144460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2145460a90540b045c102012da2492999557e6840526Jim Grosbach } 2146460a90540b045c102012da2492999557e6840526Jim Grosbach 2147460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2148460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 2149460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 2150460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2151460a90540b045c102012da2492999557e6840526Jim Grosbach } 2152460a90540b045c102012da2492999557e6840526Jim Grosbach 2153460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 2154460a90540b045c102012da2492999557e6840526Jim Grosbach 2155460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 2156460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 2157460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 215899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 215999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 216050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2161a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2162a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2163fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 2164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 2165fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 2166fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 2167e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 2168e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 2169e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 2170e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 2171e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 2172fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 2173e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2174e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 2175e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2176e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 2177e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 2178e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 2179e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 2180e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 2181e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 2182e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 2183e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 2184e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 2185e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 2186e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2187e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2188e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 2189fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 2190e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2191e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 2192e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2193e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 2194e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 2195e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 2196e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 2197e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 2198e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 2199e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2200e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2203e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2204e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2205e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 220689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 220789df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 220889df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 220989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 221089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 221189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 221289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 221389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 221489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 221589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 221689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 221789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 221889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 221989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 222089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 222189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 222289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 222389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 222489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 222589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 222689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 222789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 222889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 222989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 223089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 223189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 223289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 223389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 223489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 223589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 223689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 223789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 223889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 223989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 224089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 224143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2242fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2243fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2244f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 224543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2246e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 2247e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 2248c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2249c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2250e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2251fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2252e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 2253f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2254e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2255e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 2256fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2257f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2258fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 2259fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 226043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2261fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2262fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2263f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 226443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2265fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2266fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2267c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2268c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2269fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2270fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2271fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 2272f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2273fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2274fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2275fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2276f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2277e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2278e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 22799b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 22809b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}' 22819b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 22829b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22839b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc S = Parser.getTok().getLoc(); 22849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 22859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // If this isn't a '{', this isn't a coprocessor immediate operand. 22869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 22879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_NoMatch; 22889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '{' 22899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 22909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCExpr *Expr; 22919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 22929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (getParser().ParseExpression(Expr)) { 22939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "illegal expression"); 22949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 22959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 22969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 22979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 22989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 22999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 23009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 23019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach int Val = CE->getValue(); 23029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 23039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // Check for and consume the closing '}' 23049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 23059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 23069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc E = Parser.getTok().getLoc(); 23079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '}' 23089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 23099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 23109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_Success; 23119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach} 23129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 2313d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 2314d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 2315d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 2316d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 2317d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 2318d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 2319d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 2320d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2321d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 2322d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 2323d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 2324d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2325d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2326d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2327d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2328d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2329d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2330d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2331d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2332d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2333d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 2334d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2335d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 233650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 23371355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 233818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 2339a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 2340e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 2341d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 2342d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 234316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2344d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 2345d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 2346d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 2347d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 2348d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 2349d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2350d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach MCRegisterClass *RC; 2351d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2352d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2353d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2354d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2355d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2356d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2357d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 2358d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2359e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 2360d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 2361d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // space for that many. 2362d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2363d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Store the first register. 2364d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2365d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2366d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 2367d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 2368d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 2369d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2370d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2371d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2372d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2373d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2374d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 2375d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2376d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2377d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2378d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2379d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2380d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2381d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2382d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2383d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2384d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2385d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2386d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2387d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2388d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2389d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2390d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2391d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2392d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2393d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2394d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2395d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2396d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2397d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2398d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2399d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 24002d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2401d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2402d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2403d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2404d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2405d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg)) 2406d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2407d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2408d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2409d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2410d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2411d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2412d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2413d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2414d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2415d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2416d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2417d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2418d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2419d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2420e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 242150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 242250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2423d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2424d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 2425862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list 2426862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2427862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2428862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if(Parser.getTok().isNot(AsmToken::LCurly)) 2429862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_NoMatch; 2430862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2431862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc S = Parser.getTok().getLoc(); 2432862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '{' token. 2433862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 2434862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2435862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int Reg = tryParseRegister(); 2436862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2437862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2438862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2439862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2440862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2441862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned FirstReg = Reg; 2442862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count = 1; 2443862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach while (Parser.getTok().is(AsmToken::Comma)) { 2444862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat the comma. 2445862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach RegLoc = Parser.getTok().getLoc(); 2446862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int OldReg = Reg; 2447862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Reg = tryParseRegister(); 2448862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2449862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2450862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2451862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2452862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // vector register lists must also be contiguous. 2453862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // It's OK to use the enumeration values directly here rather, as the 2454862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // VFP register classes have the enum sorted properly. 2455862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg != OldReg + 1) { 2456862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "non-contiguous register range"); 2457862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2458862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2459862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2460862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ++Count; 2461862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2462862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2463862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2464862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) { 2465862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(E, "'}' expected"); 2466862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2467862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2468862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '}' token. 2469862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2470862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E)); 2471862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_Success; 2472862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach} 2473862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 247443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2475f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 247643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2477706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2478706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2479706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2480706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 2481706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2482706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2483706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 2484706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 2485032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 2486706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 2487032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 2488706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 2489706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 2490032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 2491706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 2492032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 2493706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 2494706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 2495706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 2496706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2497706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 2498f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2499706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2500706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2501706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2502f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2503706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 2504706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 250543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2506a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 250743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2508a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2509a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2510a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2511a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 2512a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 25132dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // An iflags string of "none" is interpreted to mean that none of the AIF 25142dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // bits are set. Not a terribly useful instruction, but a valid encoding. 2515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 25162dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (IFlagsStr != "none") { 25172dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 25182dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 25192dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("a", ARM_PROC::A) 25202dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("i", ARM_PROC::I) 25212dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("f", ARM_PROC::F) 25222dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Default(~0U); 25232dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 25242dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // If some specific iflag is already set, it means that some letter is 25252dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // present more than once, this is not acceptable. 25262dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (Flag == ~0U || (IFlags & Flag)) 25272dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson return MatchOperand_NoMatch; 25282dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 25292dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson IFlags |= Flag; 25302dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson } 2531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2532a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2533a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2534a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2535a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 2536584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 2537584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 253843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2539584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 254043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2541584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2543584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2544584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 2545584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2546acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 2547acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 2548acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2549acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 2550acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 2551acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 2552acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 2553acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 2554acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 2555acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 2556acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 2557acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 2558acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 2559acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 2560acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 2561acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 2562acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 2563acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 2564acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2565acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 2566acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2567acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2568acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 2569acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 2570acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2571acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2572acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 2573acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2574acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 2575acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 2576acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2577584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 2578584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 2579584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 2580b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 2581584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 2582584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 2583584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2584584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 2585584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 2586584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2587584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 2588584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2589584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 2590584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 2591b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 2592584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 2593584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 2594584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2595584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 25964b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 2597584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 2598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 2600bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 26014b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 2602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 260356926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 260456926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 2605584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 2606584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 2607584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 2608584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 2609584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 2610584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 2611584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2612584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2613584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 2614584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 2615584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 2616584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2617584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 2618584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2619584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 2620584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2621584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2622584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 2623584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 2624584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 2625584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2626584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2627584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 2628584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 2629584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2630584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2631584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2632584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 2633a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 2634a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2635f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2636f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 2637f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 2638f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2639f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2640f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2641f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2642f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2643f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 2644f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 2645f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 2646f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 2647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2648f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2649f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2650f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 2651f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2652f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 2653f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2654f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2655f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2656f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2657f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 2658f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2659f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 2660f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 2661f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2662f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 2663f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2664f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2665f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2666f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 2667f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 2668f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2669f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2670f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 2671f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 2672f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 2673f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2674f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2675f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2676f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 2677f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2678f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 2679f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 2680f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2681c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2682c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2683c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2684c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 2685c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2686c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2687c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2688c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2689c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 2690c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 2691c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 2692c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 2693c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 2694c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2695c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 2696c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2697c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2698c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2699c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 2700c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 2701c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 2702c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 2703c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 2704c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2705580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 2706580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 2707580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 2708580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 2709580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 2710580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2711580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2712580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 2713580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 2714580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2715580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2716580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2717580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2718580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 2719580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 2720580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 2721580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 2722580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 2723580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 2724580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 2725580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2726580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2727580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2728580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 2729580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2730580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 2731580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2732580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2733580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2734580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2735580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 2736580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2737580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 2738580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2739580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2740580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 2741580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2742580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2743580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2744580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 2745580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 2746580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2747580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2748580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2749580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 2750580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 2751580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2752580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 2753580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 2754580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2755580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 27560afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 27570afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 27580afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 27590afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 27600afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 2761580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 2762580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 2763580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2764580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 2765580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 2766580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2767580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2768580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2769580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2770580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 2771580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 2772580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2773580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 2774580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 2775580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 27767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 27777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 27787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 27797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 27807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 27817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 27827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 2783326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2784326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 27857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 2786326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 2787326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 27887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 27897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 27907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 27917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 27927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 27937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 27947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 27957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 27967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 27977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 27987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 27997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 28007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 28017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 28027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 28037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 28047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 28057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 28067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 28077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 28087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 28097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 28107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 28117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 28127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 28137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 28147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 28157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 28167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 28177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 28187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 28197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 28207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 28217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 28227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 28237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2824293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2825293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2826293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2827293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2828293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2829293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2830293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2831293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2832293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2833293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2834293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2835293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2836293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2837293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2838293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2839293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2840293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2841293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2842293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2843293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2844293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2845293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2846293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2847293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2848293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2849293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2850293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2851293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2852293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2853293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2854293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2855293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2856293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2857293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2858293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2859293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2860293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2861293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2862293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2863293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2864293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2865293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2866293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2867293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2868293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2869293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2870293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2871293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2872293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2873293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2874293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2875293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2876293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2877293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2878293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2879293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2880293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2881293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2882293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2883293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2884293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2885293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2886293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2887293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2888293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2889293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 28907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 28917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2893f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2894f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2895f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 28967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 28977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 28987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 28997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 29007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 29017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 29027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 290316578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 29047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 29057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 29067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 29077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 29087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 29097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 291016578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 29117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 29127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 29137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 29147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 29157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 29167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 29177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 29187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 29197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 29207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 29217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 29227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2923f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2924f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 29250d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 29260d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 29270d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 29280d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 29290d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2930f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2931f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2932f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 29337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 29347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 29357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 29367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2937251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2938251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2939251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2940251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2941251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2942251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2943251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2944251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2945251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2946251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2947251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2948251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2949251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2950251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2951251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2952251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2953251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2954251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2955251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2956251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2957251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2958251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2959251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2960251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2961251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2962251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2963251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2964251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2965251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2966251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2967251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2968251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2969251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2970251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2971251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2972251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2973251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2974251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2975251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2976251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2977251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2978251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2979251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2980251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2981251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2982251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2983251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2984251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2985251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2986251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2987251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2988251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2989251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2990251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2991251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2992251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2993251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2994251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2995251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2996251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2997251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2998251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2999251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3000251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3001251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 3002251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 3003251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3004251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3005251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 3006251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3007a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 3008a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3009a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3010a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3011a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 3012a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3013a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3014a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3015a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3016a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3017a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3018a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3019a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3020a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3021a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3022a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3023a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3024a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3025a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 3026a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3027a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3028a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3029a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 3030a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3031a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3032a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3033a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3034a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3035a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3036a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3037a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3038a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3039a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3040a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3041a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3042a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3043eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3044eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3045eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3046eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 3047eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3048eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3049eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3050eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3051eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 3052eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3053eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3054eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3055eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3056eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 3057eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 3058eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3059ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3060ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3061ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3062ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 3063ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3064ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3065ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 3066ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3067ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3068ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3069ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3070ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 3071ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 3072ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 30731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3074ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3075ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3076ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 30771355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3078ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3079ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3080ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 3081ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3082ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3083ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 30847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3085ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3086ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3087ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3088ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 30899ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 30909ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 30919ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 30929ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 30939ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 30949ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 30959ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 30969ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 30979ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 30989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 30999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 31009ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 31019ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 31029ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 31039ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 31049ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 31059ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 3106548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 3107548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3108548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3109548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 3110548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 3111548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3112548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 3113548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3114548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3115548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 3116548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3117548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 3118548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 3119548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 31201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3121ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3123ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 31241355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3125ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3128548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3129548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3130548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 31317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 31327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 31337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 31347b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 31357b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 31367b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 31377b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 31387b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 31397b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31407b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 31417b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 31427b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 31437b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 31447b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 31457b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 31467b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 31477b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 31487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 31497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 31507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 31517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 31527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 31537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3155ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 31567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 31577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 31587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 31597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 31607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 31617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 31627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3163ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3164ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3165ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3166ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 31677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 3168ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3169ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3170ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 31717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 31727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3174aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3175ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3176ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 31777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 31787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 31797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 31807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 31817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 31827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 31837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 31847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 3185aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 31867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 31877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 31887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 31897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 31907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 31917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 31937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 31947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 31957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 31967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 31977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 31987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 31997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 32007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3201ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3202ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3203ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3204ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 32057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 3206ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3207ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3208ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 32097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 32107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3211ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3212ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 32137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3214ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 32157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 32167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 32177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 32187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 32197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3220ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3221ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3222ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3223ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 32242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 32252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 32262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 32272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 32282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 32292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 32312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 32322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 32332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 32342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 32352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 32362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 32372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 32382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 32392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 32402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 32412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 324214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 324314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 324414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 324514605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 324614605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 324714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 324814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 324914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 325014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 325114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 325214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 325314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 325414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 325514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 325614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 325714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 325814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 325914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 3260623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 3261623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3262623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3263623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 3264623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 3265623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3266623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3267623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 3268623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3269623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 3270623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3271623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 3272623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 3273623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 327488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 327588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 327688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 327788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 327888ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 327988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 328088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 328188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 328288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 32837a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 32847a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 32857a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 32867a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 328788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 32887a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 328988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 329088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 329188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 329288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 329388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 32947a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // If we have a three-operand form, use that, else the second source operand 32957a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // is just the destination operand again. 32967a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach if (Operands.size() == 6) 32977a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 32987a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach else 32997a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach Inst.addOperand(Inst.getOperand(0)); 330088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 330188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 330288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 330388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 3304623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 3305e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 33069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 330750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 33087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 331018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3311a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 3312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3313b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 3314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 331518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 33161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 33177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 33187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 3319a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 33200571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 33210571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 33220571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 33237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 33240571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 33257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 3326762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 3327b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 3328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 33297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 333057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 0, 0, false, S, E)); 333103f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 3332fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3333fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 3334fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3335fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3336fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 3337fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 3338fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 33397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 33407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 334150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 33427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 33437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 334450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 334557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a ':', it's an alignment specifier. 334657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Colon)) { 334757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the ':'. 334857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 334957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 335057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCExpr *Expr; 335157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (getParser().ParseExpression(Expr)) 335257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return true; 335357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 335457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // The expression has to be a constant. Memory references with relocations 335557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // don't come through here, as they use the <label> forms of the relevant 335657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // instructions. 335757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 335857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!CE) 335957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error (E, "constant expression expected"); 336057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 336157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Align = 0; 336257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach switch (CE->getValue()) { 336357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach default: 336457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "alignment specifier must be 64, 128, or 256 bits"); 336557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 64: Align = 8; break; 336657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 128: Align = 16; break; 336757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 256: Align = 32; break; 336857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 336957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 337057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Now we should have the closing ']' 337157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 337257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 337357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "']' expected"); 337457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat right bracket token. 337557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 337657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Don't worry about range checking the value here. That's handled by 337757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // the is*() predicates. 337857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 337957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, Align, 338057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 338157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 338257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 338357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // operand. 338457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 338557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 338657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the '!'. 338757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 338857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 338957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return false; 339057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 339157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 339257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a '#', it's an immediate offset, else assume it's a register 33937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 33947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 33957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 33967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 339750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 33980da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 33997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 34007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 34017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 340205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 34037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 34047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 34057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 34067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 34077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 34087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 34097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 34100da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 34110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 34120da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 34130da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 34140da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 34157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 34167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 34177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 34187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 34197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 342005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 34217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 34227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 34237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 342457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, 0, 342557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 3426a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 34277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 34287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 34297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 34307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 34317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 3432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 34337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 34347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 34359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 3436d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 34377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 34387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 34397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 34407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 34417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 34427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 34437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 34447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 34457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 34469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 34477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 34487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 34497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 34507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 34517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 34527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 34537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 34540d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 34557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 34567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 34570d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 34587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 34599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 346016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 34617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 34627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 34637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 34647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 34657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 34667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 34677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 346857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ShiftType, ShiftImm, 0, isNegative, 34697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 34707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3471f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3472f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 3473f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3474f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3475f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 3476f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 34779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 34789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 34799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 34809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 34817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 3482a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 3483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 34847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 34857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 34867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 34877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 348818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 349138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 3492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 34930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 3494a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 34950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 3496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 34970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 3498a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 34990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 3500a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 35010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 3502a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 35037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 3504b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 3505a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 35067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 35077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 35087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 35097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 35107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 35117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 35127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 35137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 35147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 35159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 35167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 35177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 35187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 35197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 35207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 35217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 35227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 35237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 35247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 35257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 35267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 35277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 35287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 35297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 35307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 35317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 3532a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3533a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 3534a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3535a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 35369d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 35379d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 35389d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 35399d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 35409d39036f62674606565217a10db28171b9594bc7Jim Grosbach 35419d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) 35429d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 35430e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 35440e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Disambiguate the VMOV forms that can accept an FP immediate. 35450e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <sreg>, #imm 35460e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f64 <dreg>, #imm 35470e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <dreg>, #imm @ vector f32x2 35480e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <qreg>, #imm @ vector f32x4 35490e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // 35500e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // There are also the NEON VMOV instructions which expect an 35510e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // integer constant. Make sure we don't try to parse an FPImm 35520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // for these: 35530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.i{8|16|32|64} <dreg|qreg>, #imm 35540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]); 35550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!TyOp->isToken() || (TyOp->getToken() != ".f32" && 35560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach TyOp->getToken() != ".f64")) 35570e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return MatchOperand_NoMatch; 35580e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 35599d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 35609d39036f62674606565217a10db28171b9594bc7Jim Grosbach 35619d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 35629d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 35639d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 35649d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 35659d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 35669d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35679d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 35689d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 35699d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 35709d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 35719d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 35729d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 35739d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 35749d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 35759d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 35769d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 35779d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 35789d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35799d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 35809d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 35819d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35829d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 35839d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 35849d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 35859d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 35869d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 35879d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 35889d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35899d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 35909d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 35919d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35929d39036f62674606565217a10db28171b9594bc7Jim Grosbach 35939d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 35949d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 35959d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 35969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 35979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 35981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3599fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 3600762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 3601fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3602fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 3603fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 3604f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 3605f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 3606fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 3607f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 3608f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 3609f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 3610f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 3611f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 3612fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3613a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 3614146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 3615146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 361650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 361719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 36185cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 36191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 362050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 36210d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 362219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 36230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 362419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 362519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 36265cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 36275cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 36285cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 36295cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 36305cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 36315cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 3632e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 3633e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 3634e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 363519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 363667b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 363767b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 3638515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 3639515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 3640515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 3641762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3642515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 364350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 3644762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 364550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 364650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 364750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 3648a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 36491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 3650d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 36511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 365263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 3653079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 3654079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 3655762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3656b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 365763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 3658515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 3659515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 366050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 366163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 366263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (!CE) { 366363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson Error(S, "constant expression expected"); 366463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return MatchOperand_ParseFail; 366563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 366663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson int32_t Val = CE->getValue(); 366763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (isNegative && Val == 0) 366863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 3669762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 367050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 367150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 367263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 36739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 36749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 36757597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 36767597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 36777597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 36781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 36799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 36809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 36817597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 36827597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 36839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 36849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 36857597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 36867597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 36879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 36887597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 36899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 36909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 3691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3692a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3693a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 36941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 36957597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 36961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 36977597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 36989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 36999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 37008a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 37019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 37029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 37039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 37049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 37059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 37069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 37079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 37089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 37099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 37107597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 37119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 37127597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 37139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 37149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 37159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 37169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 37179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 37189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 37199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 37209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 37219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 37229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 37239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 37249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 37259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 37269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 3727352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 3728352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 3729352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 3730badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 373189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 37321355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 37335f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 37345f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 373589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 373689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 3737352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 3738352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 3739a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 3740352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3741badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 3742352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 3743352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 37445f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 37455f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 37465f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 37475f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 37485f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 37495f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 37505f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 37515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 3752352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3753badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 37543f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 37553f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 3756ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 375771725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 375804d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 37592f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 37603f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 37613f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 37623f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 37633f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 37643f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 37653f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 37663f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 37673f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 37683f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 37693f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 37703f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 37713f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 37723f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 37733f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 37743f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 37753f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 37763f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 37773f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 37783f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 37793f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 37803f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 37813f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 37823f00e317064560ad11168d22030416d853829f6eJim Grosbach } 378352925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 3784345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3785352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 3786352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 3787352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 378800f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 37895f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 37905f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 37915f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 3792e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 3793e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 3794352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 3795352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 3796352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 3797352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3798a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 3799a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 3800a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 3801a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 3802a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 3803a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 3804a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 3805a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 3806a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 3807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 3808a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 3809a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 3810a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3812a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 381389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 381489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 381589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 381689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 381789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 381889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3819352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3820352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 38213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 38223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 38233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 38243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 38253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 3826fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 38271355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 3828fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 3829eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 3830eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 38313443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 3832eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 3833d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 3834eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 3835d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 38363443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 3837d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 3838d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 3839eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 3840fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 3841eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 38423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 3843eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 3844eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 3845eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 3846eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 3847ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 3848ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 38490780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 38502bd0118472de352745a2e038245fab4974f7c87eJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" || 38512bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "ldc2" || Mnemonic == "ldc2l" || 38522bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) || 38534af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 38544af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 38551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 38563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 3857fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 38583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 3859fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 3860fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 3861fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 386263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 3863fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 3864fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 3865badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 3866badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3867d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 3868d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 386920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 387020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 3871d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3872d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 3873d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 3874d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 3875d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 3876d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 3877d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 3878d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 3879d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 38808adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 3881d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 3882d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 3883d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3884d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 38853912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 38863912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 38873912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 38883912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 38893912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 38903912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 38913912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 38923912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 389372f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 389420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 389520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 389620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 3897f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 3898f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 3899f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 390072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 390172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 390272f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 390320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 390420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 390520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 390672f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 3907f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 3908f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 390920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 391020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 391120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 3912f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 3913f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 391420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 391520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 391620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 391720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 391820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 391920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 392020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 392120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 392220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 392320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 392420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 392520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 392620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 392720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 392820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 392964944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 393020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 393120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 393220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 393320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 393420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 393520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 393620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 393720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 393820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 393964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 394064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 394164944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 394264944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 394364944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 394464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 394564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 394664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 394764944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 394864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 394964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 395064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 395164944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 395264944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 395364944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 395464944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 395564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 395664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 395764944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 395864944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 395964944f48a1164c02c15ca423a53919682a89074cJim Grosbach 396064944f48a1164c02c15ca423a53919682a89074cJim Grosbach 396120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 3962f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 3963f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 3964f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 3965f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 3966f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 3967f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 3968f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 396972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 397072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 397172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 397272f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 39733912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 3974d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 3975d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 3976d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3977badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 3978badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 3979badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3980badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 3981badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 3982ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 3983badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3984352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 3985352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 3986a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 3987352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 398889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 39891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 399089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 3991badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 39920c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 39930c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 39940c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 39950c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 39960c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 39970c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 3998ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 3999ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 400089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 400189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 400289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 400389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 400489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 400589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 4006f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 4007f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 4008f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 4009f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 4010f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 401189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 401289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 401389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 401489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 401589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 4016f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 401789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 401889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 401989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 402089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 402189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4022f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 402389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 402489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4025ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 4026ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 40279717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 40283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 40293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 40303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 40313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 40323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 40333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 40343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 40353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 40361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 40373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 403833c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 403933c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 404033c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 404133c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 4042ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 404333c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 404433c16a27370939de39679245c3dff72383c210bdJim Grosbach } 4045c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 4046c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 4047c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 4048c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 4049c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 4050c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 4051c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 405233c16a27370939de39679245c3dff72383c210bdJim Grosbach 40533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 4054f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 4055f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 40563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 4057f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 4058f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 40593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 40603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 40613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 4062f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 4063f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 40643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 4065f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 4066badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 4067345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4068a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 4069a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 4070a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 4071a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 4072a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 4073a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4074a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 4075345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 40765747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 40775747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 40785747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 4079a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 4080a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40814d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // For now, we're only parsing Thumb1 (for the most part), so 40824d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // just ignore ".n" qualifiers. We'll use them to restrict 40834d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // matching when we do Thumb2. 408481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 408581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 408681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 408781d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 40885747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 40895747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 40905747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 40915747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 4092a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 40931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4094cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4095cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4096cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4097a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4098a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 4099b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 4100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 41021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4103cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4104cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4105cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4107a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 410816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4109cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 4110186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach SMLoc Loc = getLexer().getLoc(); 4111cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4112186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach return Error(Loc, "unexpected token in argument list"); 4113cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4114146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 411534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 4116ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4117d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 4118d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 4119d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 412020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 412120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 412220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 412320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 412420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 4125ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4126ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 4127ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 4128ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 4129ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4130cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 4131cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 4132cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 413321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // a k_CondCode operand in the list. If we're trying to match the label 413421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // version, remove the k_CondCode operand here. 4135cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 4136cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 4137cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4138cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 4139cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 4140cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 4141857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 4142857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 4143857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 4144857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 4145857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 4146857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 4147857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4148857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4149857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4150857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 4151857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 4152857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 415368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 415468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 415568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 415668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 415768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 415868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 415968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 416068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 416168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 416268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 416368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4164857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 4165857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4166857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4167934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 4168934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 4169934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 4170934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4171934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4172934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4173934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 4174934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 4175934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4176934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 4177934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4178934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4179934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 41809898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 4181ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4182ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4183189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 4184aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 4185aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 4186aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 4187aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 4188aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 4189aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 4190aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 4191aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 4192aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 4193aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 4194aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 4195aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 4196aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 4197aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 4198aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 4199aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 4200aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 4201aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 420276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 420376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 420476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 420576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 420676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 420776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 420876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 420976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 421076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 421176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 421276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 4213f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 4214f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 4215f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 4216f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 4217f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[]; 4218f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 4219f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 4220f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 4221f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 4222f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4223189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 4224189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 4225189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 4226189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4227f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 4228f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 4229f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 4230b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 4231b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 4232b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 4233b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 4234f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 4235f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 4236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 4237f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 4238a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 4239f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 4240f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 4241f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 4242f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 4243f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 4244f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 4245f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 4246f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 4247f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 4248f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 4249f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 4250f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 4251f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 4252f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 4253f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 4254f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 4255f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 4256c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 4257f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 4258f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 425951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 426051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 4261f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 4262f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4263189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 42642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 42652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 42662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 4267189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 4268189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4269189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 4270189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4271189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 4272189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 4273189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 4274189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4275189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 427614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 427714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 427814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 427914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 428014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 428114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 428214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 428314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 428414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 428553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 428653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 4287189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 4288189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4289189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4290189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 4291189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 429214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 4293189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 4294189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4295189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4296fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 4297fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 4298fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 4299fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 4300fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 4301fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 4302fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 4303fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 430400c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 4305fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 430693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 430776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 430876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 430976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 431076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 431176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 431293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 431393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 431493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 43157260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 43167260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 43177260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 4318aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 431976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 4320aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 4321aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 432293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 432376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 432493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 432593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 432676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 432776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 4328aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 43297260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 43307260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 43317260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 433293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 433393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 433493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 433576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 433676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 433776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 433876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 433976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 434076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 434176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 43426dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 4343aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 4344aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 4345aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4346aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 43476dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 43486dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 43496dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 4350aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 4351aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 4352aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4353aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 43546dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 43556dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 43561e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 43571e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 43588213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 43591e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 43601e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 43611e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 43621e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 4363189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4364189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4365189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4366189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 4367189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4368f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 4369f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 4370f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4371f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 4372f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 4373f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 4374f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 4375f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 4376f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 4377f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 4378f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 4379f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4380f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4381f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 4382f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 4383f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 4384f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4385f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4386f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 4387f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4388f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 4389f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 4390f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 4391f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 4392f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 4393f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 4394f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 4395f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 4396f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4397f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4398f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 4399f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 4400f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4401f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4402f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 4403f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 4404f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 440589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 44060f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 44070f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 44080f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 44090f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 44100f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 441189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 441289e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 4413f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 4414f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 4415f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 4416f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 4417f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 4418f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 4419f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 4420f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 442151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 442251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 442351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 442451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 442551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 442651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 442751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 442851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 442951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 443051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 4431c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 4432a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 4433a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) 4434c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 4435c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 4436395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 4437395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 4438395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) 4439395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 44403ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 444176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 444276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 444376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 444476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 444576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 444676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 444776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 444876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 444976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 445076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 445176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 445276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 445376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 445476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 445576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 445676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 445776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 445876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 445976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 446076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 446176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 446276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 446376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 446476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 44658213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 44668213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 44678213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 44688213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 44698213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 44708213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 44718213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 44728213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 44738213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 44748213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 44758213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 44768213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 44778213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 44781ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 44791ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 44801ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 44811ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 44821ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 4483c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 4484c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 4485c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 44861ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 44871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 44881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 44891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 44901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 44911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 44921ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 44931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 44941ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 44951ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 44961ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 44971ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 44981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 44991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 45001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 45011ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 45021ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 45031ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 45041ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 45051ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 45061ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 45071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 45081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 45091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 45101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 45111ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 45121ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 45131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 45141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 45151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 45161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 45171ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 45181ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 45191ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 4520326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 452150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 452250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 452350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 4524326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 4525326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 4526326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4527326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4528326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 4529326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4530326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 453150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 453250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 453350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 453450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 453550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 453650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 453750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 453850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 4539326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 4540326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 4541326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 4542326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 4543326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 4544326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4545326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 4546326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 4547326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 4548326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 4549326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 455089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 455189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 455289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 455389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 455489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 455589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 455689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 455789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 455889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 4559f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 4560f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 456189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 456289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 456389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 456489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 456589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 456689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 456789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 4568f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4569f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 4570f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 4571f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 4572f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 4573f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 4574f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 4575f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 457689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 457789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4578f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4579f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 4580f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 458147a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 458247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 458347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 4584194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 4585194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 458647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 458747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 458847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 458947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 459047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 459147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 459247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 459347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 459447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 459547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 459647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 459747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 459847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 459947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 460047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 460147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 4602f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 4603f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 460447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 4605f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 4606f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 4607f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 460847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 4609194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 4610194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 4611194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 4612194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4613194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 4614194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 4615194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 46164ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 4617194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 4618194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 4619194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 462047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 462147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 462247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 4623fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 4624fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 4625fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4626fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 4627fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 4628fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 462919cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 4630193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 4631193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 463219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 4633e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 4634189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 4635189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 4636a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 4637a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 4638a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 4639a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4640189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 4641a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 4642189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4643f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 4644f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 4645f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 4646f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 4647a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 4648a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 4649a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 4650a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4651a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 4652fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 4653fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 4654e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 4655e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 4656e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 4657e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 4658e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 4659e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 4660e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 4661e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 466216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4663e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 4664e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 4665e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 466616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4667e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 4668e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 4669e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 467047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 4671b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 467288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 467388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 4674f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 4675f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 467647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 467747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 4678194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 4679194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 4680194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 4681194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 4682fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 468316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4684c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 4685146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 4686fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 4687fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 46881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 4689ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 4690ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 4691ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 46921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 4693515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 46941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 4695515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 46961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 4697515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 46981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 4699515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 47001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 4701ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4702ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4703ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 4705ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 47061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 4707ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 4708ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 4709ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 4710ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 4711ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4712ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4713aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 4714ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4715ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 4716ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 471716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4718ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 4719ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 4720ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 4721b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4722ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4723ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4724ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4725b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4726ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 4727ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4728ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 4730515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 47311355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 4732515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4733515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4734b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4735515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4736515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 4737515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 4738515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4739515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4740515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4741515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 47421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 4743515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 47441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 47456469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 47466469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 47476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 47486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 47496469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 47506469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 47516469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 47526469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 47536469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 47546469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 47556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 47566469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 47576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 47586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4759515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4760515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4761b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4762515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 47636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 47646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 47656469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 47666469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 47676469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4768642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 4769642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 4770642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 4771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4772515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4773515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 47741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 4775515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 47761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 477718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4778515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 4779515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 478038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 478158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 4782b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 478358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 47849e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 4785515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4786515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 4787515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4788515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 478918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4790b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4791515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4792515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 4793515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4794515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4796515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 47971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 4798515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 47991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 480018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4801515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 4802515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 480318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 480458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 4805b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 480658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 4807b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4808515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4809515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 4810515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 481218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4813b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4814515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 481532869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 481698447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 4817ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 481898447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 481932869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 482098447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 4821ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 482298447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 4823eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 48242a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 4825515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4826515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4827515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 482890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 482990b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 48309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 4831ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 483294b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 483394b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 483490b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 4835ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 48363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 48370692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 48380692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 48393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 4840