ARMAsmParser.cpp revision b6310316dbaf8716003531d7ed245f77f1a76a11
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 918280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach bool isVecListTwoD() const { 919280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach if (Kind != k_VectorList) return false; 920280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach return VectorList.Count == 2; 921280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach } 922280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach 923cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach bool isVecListThreeD() const { 924cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach if (Kind != k_VectorList) return false; 925cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach return VectorList.Count == 3; 926cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach } 927cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach 928b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach bool isVecListFourD() const { 929b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach if (Kind != k_VectorList) return false; 930b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach return VectorList.Count == 4; 931b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach } 932b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach 933460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex8() const { 934460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 935460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 8; 936460a90540b045c102012da2492999557e6840526Jim Grosbach } 937460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex16() const { 938460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 939460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 4; 940460a90540b045c102012da2492999557e6840526Jim Grosbach } 941460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex32() const { 942460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 943460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 2; 944460a90540b045c102012da2492999557e6840526Jim Grosbach } 945460a90540b045c102012da2492999557e6840526Jim Grosbach 9460e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach bool isNEONi8splat() const { 9470e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (Kind != k_Immediate) 9480e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return false; 9490e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9500e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Must be a constant. 9510e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!CE) return false; 9520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach int64_t Value = CE->getValue(); 9530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // i8 value splatted across 8 bytes. The immediate is just the 8 byte 9540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // value. 9550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return Value >= 0 && Value < 256; 9560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 957460a90540b045c102012da2492999557e6840526Jim Grosbach 958ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach bool isNEONi16splat() const { 959ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Kind != k_Immediate) 960ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return false; 961ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 962ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // Must be a constant. 963ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (!CE) return false; 964ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach int64_t Value = CE->getValue(); 965ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // i16 value in the range [0,255] or [0x0100, 0xff00] 966ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00); 967ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 968ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 9696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32splat() const { 9706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 9716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 9726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 9746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 9756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 9766248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X. 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 } 9826248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 9836248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach bool isNEONi32vmov() const { 9846248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Kind != k_Immediate) 9856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return false; 9866248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9876248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // Must be a constant. 9886248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (!CE) return false; 9896248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach int64_t Value = CE->getValue(); 9906248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 9916248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 9926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach return (Value >= 0 && Value < 256) || 9936248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x0100 && Value <= 0xff00) || 9946248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x010000 && Value <= 0xff0000) || 9956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01000000 && Value <= 0xff000000) || 9966248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 9976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 9986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 9996248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1000f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach bool isNEONi64splat() const { 1001f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (Kind != k_Immediate) 1002f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return false; 1003f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1004f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // Must be a constant. 1005f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if (!CE) return false; 1006f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1007f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // i64 value with each byte being either 0 or 0xff. 1008f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i) 1009f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 1010f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach return true; 1011f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1012f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 10133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 101414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 101514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 101614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 101714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 10183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 10193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 10203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 10213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 10223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 10238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1024345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 10258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 102604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 102704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 10288462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 10298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1030fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 1031fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1032fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 1033fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 10359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 10369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10379b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(getCoproc())); 10389b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 10399b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 10409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 10419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10429b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val)); 10439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 10449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 104589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 104689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 104789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 104889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 104989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 105089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 105189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 105289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 105389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 105489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 1055d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 1056d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1057d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 1058d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1059d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 1060a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 1061a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 1062a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 1063a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1064a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1065af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 1066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1067af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 1068af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 1069af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 1070e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 1071af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 1072e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1073e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1074af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 1075152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 1076af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 1077af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 107892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 1079af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 108092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 108192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1082580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 10830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 1084580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 1085580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 10860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 10870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 108887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 10897729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 10905fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 10915fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 10927729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 10937729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 109487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 109587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 10960f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 10970f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 10980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 10990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 11000f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 11010f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 11020f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 11030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 11047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 11057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 11077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 11087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 11097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1110293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1111293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1112293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 1113293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 1114293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 1115293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1116293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1117293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 1118293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 1119293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1120293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 11213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 11226b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11236b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 11246b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 11256b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 11269d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 11279d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11289d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 11299d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 11309d39036f62674606565217a10db28171b9594bc7Jim Grosbach 1131a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1132a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1133a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 1134a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 1135a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1136a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1137a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1138a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 113972f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 114072f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 114172f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 114272f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 114372f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 114472f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 114572f39f8436848885176943b0ba985a7171145423Jim Grosbach } 114672f39f8436848885176943b0ba985a7171145423Jim Grosbach 114772f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 114872f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 114972f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 115072f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 115172f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 115272f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 115372f39f8436848885176943b0ba985a7171145423Jim Grosbach } 115472f39f8436848885176943b0ba985a7171145423Jim Grosbach 11556b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 11566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 11586b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 11596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 116083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 116183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 116283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 116383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 116483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 116583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 11667c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11677c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 11687c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 11697c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 11707c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 117183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 117283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 117383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 117483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 1175f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1176f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1177f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1178f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1179f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1180f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1181f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1182f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 11834a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 11844a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 11854a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 11864a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 11874a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11884a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 11894a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 11904a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 1191fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 1192fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1193fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 1194fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 1195fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 1196ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 1197ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1198ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 1199ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 1200ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 1201ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 1202ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1203ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 120470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 120570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 120670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 120770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 120870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 120970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 121070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 121170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 121270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1213ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1214ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1215f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 1216f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1217f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 1218f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1219f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1220f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1221f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1222f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1223f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1224f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1225f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1226f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1227f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1228f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 12296bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 12306bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 12316bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 12326bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 12336bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 12346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 12353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 12363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 12373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 123816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1239c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 1240c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1241c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 1242c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1243c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1244706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1245706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1246706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1247706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1248706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 12497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 12507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1251e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1252505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1253505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 125457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 125557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 125657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 125757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 125857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 125957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 12607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 12617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1262e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1263e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 12647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 12667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 12677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 12687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 12697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 12707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 12717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 1272e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1273e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1274ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1275e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1276e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 12777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1278ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1279ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1280039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1281039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1282039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1283039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1284039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1285039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1286039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1287039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1288039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1289039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1290039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1291039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1292039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1293039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 12942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 12952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1296e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1297e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 12982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 13002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 13012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 13022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 13032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 13042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 13052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 1306e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 13072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 1308e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1309e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 13102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 13122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 13132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 13142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 131521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) { 13162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 13172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 13182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 13192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1320251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 13212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 13222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 13232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 13242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 13252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 13262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 13272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 13282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 13292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1330251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 13312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 13322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 13342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 13357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 13367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 13377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1338e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 13397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 13407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 13417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 13427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 13437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 1344e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 13457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 13477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1348a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1349a77295db19527503d6b290e4f34f273d0a789365Jim 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)); 1352a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1353a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1354a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1355b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1356b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1357b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1358e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1359e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1360b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1361b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1362b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 13637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 13647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1365e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1366e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 13677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1368ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1369ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1370f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1371f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1372f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1373f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1374a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1375f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1376a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1377a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1378a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1379a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1380a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 138121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 1382a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1383a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1384a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1385a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1386a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1387a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim 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)); 1390a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1391a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1392a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 13937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 13947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 139509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 139621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 139709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 139809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 139909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 140009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 140109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 140209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1403e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1404e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 14057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 140792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 14087f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 14097f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1410e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1411e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 14137f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 14147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 14157f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1416e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1417e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 14197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 14207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 14217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1422e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1423e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1424e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1425e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 14267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 14277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1428d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1429ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1430ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1431e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1432e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1433e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 1434ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1435ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 14367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 14377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1438e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1439e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 144014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 14413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 144260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 144360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1444e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1445e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 144660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 144748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 144848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 144938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 145038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1451e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 1452e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 145338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 145438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 145538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 145648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 145748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1458e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 1459e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 146048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 146160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 146260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1463ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1464ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1465e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1466e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1467ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1468ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1469ecd858968384be029574d845eb098d357049e02eJim Grosbach 14707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 14717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 14727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 14747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 14757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 147663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 14777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 14787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1479f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1480ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 14812bd0118472de352745a2e038245fab4974f7c87eJim Grosbach void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 14822bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 14832bd0118472de352745a2e038245fab4974f7c87eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 14842bd0118472de352745a2e038245fab4974f7c87eJim Grosbach assert(CE && "non-constant post-idx-imm8s4 operand!"); 14852bd0118472de352745a2e038245fab4974f7c87eJim Grosbach int Imm = CE->getValue(); 14862bd0118472de352745a2e038245fab4974f7c87eJim Grosbach bool isAdd = Imm >= 0; 14872bd0118472de352745a2e038245fab4974f7c87eJim Grosbach if (Imm == INT32_MIN) Imm = 0; 14882bd0118472de352745a2e038245fab4974f7c87eJim Grosbach // Immediate is scaled by 4. 14892bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 14902bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 14912bd0118472de352745a2e038245fab4974f7c87eJim Grosbach } 14922bd0118472de352745a2e038245fab4974f7c87eJim Grosbach 14937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 14947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 14957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1496f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1497f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1498f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1499f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1500f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1501f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1502f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1503f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1504f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1505f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1506f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1507f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1508ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1509ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1510584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1511584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1512584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1513584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1514584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1519a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1520862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach void addVecListOneDOperands(MCInst &Inst, unsigned N) const { 1521862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1522862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1523862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1524862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1525280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach void addVecListTwoDOperands(MCInst &Inst, unsigned N) const { 1526280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1527280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach // Only the first register actually goes on the instruction. The rest 1528280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach // are implied by the opcode. 1529280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1530280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach } 1531280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach 1532cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach void addVecListThreeDOperands(MCInst &Inst, unsigned N) const { 1533cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1534cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach // Only the first register actually goes on the instruction. The rest 1535cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach // are implied by the opcode. 1536cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1537cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach } 1538cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach 1539b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach void addVecListFourDOperands(MCInst &Inst, unsigned N) const { 1540b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1541b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach // Only the first register actually goes on the instruction. The rest 1542b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach // are implied by the opcode. 1543b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 1544b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach } 1545b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach 1546460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1547460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1548460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1549460a90540b045c102012da2492999557e6840526Jim Grosbach } 1550460a90540b045c102012da2492999557e6840526Jim Grosbach 1551460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1552460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1553460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1554460a90540b045c102012da2492999557e6840526Jim Grosbach } 1555460a90540b045c102012da2492999557e6840526Jim Grosbach 1556460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1557460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1558460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1559460a90540b045c102012da2492999557e6840526Jim Grosbach } 1560460a90540b045c102012da2492999557e6840526Jim Grosbach 15610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 15620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 15630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // The immediate encodes the type of constant as well as the value. 15640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Mask in that this is an i8 splat. 15650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 15660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00)); 15670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach } 15680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 1569ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 1570ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1571ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach // The immediate encodes the type of constant as well as the value. 1572ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1573ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach unsigned Value = CE->getValue(); 1574ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach if (Value >= 256) 1575ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value = (Value >> 8) | 0xa00; 1576ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach else 1577ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Value |= 0x800; 1578ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 1579ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach } 1580ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach 15816248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 15826248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 15836248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 15846248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 15856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 15866248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xff00) 15876248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | 0x200; 15886248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xff0000) 15896248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | 0x400; 15906248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 15916248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 15926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 15936248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 15946248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 15956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 15966248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 15976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach // The immediate encodes the type of constant as well as the value. 15986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 15996248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach unsigned Value = CE->getValue(); 16006248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach if (Value >= 256 && Value <= 0xffff) 16016248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 16026248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffff && Value <= 0xffffff) 16036248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 16046248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach else if (Value > 0xffffff) 16056248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Value = (Value >> 24) | 0x600; 16066248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Value)); 16076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach } 16086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach 1609f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 1610f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1611f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach // The immediate encodes the type of constant as well as the value. 1612f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1613f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach uint64_t Value = CE->getValue(); 1614f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach unsigned Imm = 0; 1615f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 1616f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Imm |= (Value & 1) << i; 1617f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1618f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00)); 1619f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach } 1620f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach 1621b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1622b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 162389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 162421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ITCondMask); 162589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 162689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 162789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 162889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 162989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 163089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 16313a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 163221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CondCode); 1633345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1634345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1635345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 16363a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1637345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1638345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1639fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 164021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocNum); 1641fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1642fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1643fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1644fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1645fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1646fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1647fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 164821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocReg); 1649fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1650fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1651fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1652fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1653fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1654fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 16559b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) { 16569b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocOption); 16579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->Cop.Val = Val; 16589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->StartLoc = S; 16599b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Op->EndLoc = E; 16609b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return Op; 16619b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 16629b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 1663d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 166421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CCOut); 1665d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1666d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1667d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1668d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1669d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1670d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 16713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 167221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Token); 1673762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1674762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1675762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1676762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 16773a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1678a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1679a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 168050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 168121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Register); 1682762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1683762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1684762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 16853a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1686a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1688e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1689e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1690e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1691e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1692e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 169321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1694af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1695af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1696af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1697af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1698e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1699e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1700e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1701e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1702e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 170392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 170492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 170592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 170692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 170721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1708af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1709af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1710af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 171192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 171292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 171392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 171492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 171592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1716580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 17170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 171821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1719580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1720580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 17210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 17220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 17230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 17240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 17250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 17267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 172721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_RotateImmediate); 17287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 17297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 17307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 17317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 17327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 17337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1734293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1735293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 173621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 1737293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1738293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1739293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1740293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1741293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1742293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1743293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 17447729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 17455fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1746cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 174721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach KindTy Kind = k_RegisterList; 17480f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1749d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 175021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_DPRRegisterList; 1751d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1752275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 175321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_SPRRegisterList; 17540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 17550f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 17565fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 17577729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 175824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1759cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1760cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1761cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 17628d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 17638d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 17648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 1765862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count, 1766862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc S, SMLoc E) { 1767862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ARMOperand *Op = new ARMOperand(k_VectorList); 1768862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.RegNum = RegNum; 1769862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->VectorList.Count = Count; 1770862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->StartLoc = S; 1771862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Op->EndLoc = E; 1772862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return Op; 1773862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 1774862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 1775460a90540b045c102012da2492999557e6840526Jim Grosbach static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 1776460a90540b045c102012da2492999557e6840526Jim Grosbach MCContext &Ctx) { 1777460a90540b045c102012da2492999557e6840526Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorIndex); 1778460a90540b045c102012da2492999557e6840526Jim Grosbach Op->VectorIndex.Val = Idx; 1779460a90540b045c102012da2492999557e6840526Jim Grosbach Op->StartLoc = S; 1780460a90540b045c102012da2492999557e6840526Jim Grosbach Op->EndLoc = E; 1781460a90540b045c102012da2492999557e6840526Jim Grosbach return Op; 1782460a90540b045c102012da2492999557e6840526Jim Grosbach } 1783460a90540b045c102012da2492999557e6840526Jim Grosbach 17843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 178521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Immediate); 1786762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1787762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1788762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 17893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1790cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1791cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 17929d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 179321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_FPImmediate); 17949d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 17959d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 17969d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 17979d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 17989d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 17999d39036f62674606565217a10db28171b9594bc7Jim Grosbach 18007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 18017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 18027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 18037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 18040d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 180557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment, 18067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 18073a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 180821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Memory); 1809e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.BaseRegNum = BaseRegNum; 1810e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetImm = OffsetImm; 1811e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetRegNum = OffsetRegNum; 1812e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftType = ShiftType; 1813e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftImm = ShiftImm; 181457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Op->Memory.Alignment = Alignment; 1815e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.isNegative = isNegative; 18167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 18177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 18187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 18197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 182016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1821f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1822f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1823f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 18247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 182521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 18267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1827f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1828f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1829f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1830762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1831762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 18323a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1833a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1834706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1835706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 183621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 1837706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1838706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1839706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1840706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1841706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1842a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1843a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 184421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ProcIFlags); 1845a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1846a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1847a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1848a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1849a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1850584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1851584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 185221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MSRMask); 1853584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1854584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1855584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1856584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1857584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1858a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1859a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1860a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1861a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1862b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1863fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 186421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 18659d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 18669d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 18679d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 186821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 18696a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1870fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 187121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 1872d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1873d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 187421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: { 187589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)", 187689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)", 187789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(tee)", "(eee)" }; 187889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 187989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 188089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 188189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 188221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 1883fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1884fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 188521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 1886fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1887fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 18889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach case k_CoprocOption: 18899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach OS << "<coprocessor option: " << CoprocOption.Val << ">"; 18909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach break; 189121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 1892584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1893584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 189421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 1895fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1896fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 189721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 1898706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1899706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 190021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 19016ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 1902e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach << " base:" << Memory.BaseRegNum; 19036ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1904fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 190521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 1906f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1907f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1908f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1909f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1910f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1911f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 19127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 191321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: { 1914a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1915a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1916a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1917a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1918a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1919a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1920a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1921a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 192221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 192350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1924fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 192521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 1926580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1927580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1928e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 192921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 193092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1931af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1932af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1933af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1934af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1935e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 19360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 193721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 193892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1939af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1940af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1941af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 194292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 194392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 194421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 19457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 19467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 194721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 1948293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1949293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1950293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 195121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 195221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 195321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: { 19548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 19558d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 19565fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 19575fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 19587729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 19597729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 19607729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 19618d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 19628d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 19638d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 19648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 19658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1966862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach case k_VectorList: 1967862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach OS << "<vector_list " << VectorList.Count << " * " 1968862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach << VectorList.RegNum << ">"; 1969862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach break; 197021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 1971fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1972fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1973460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 1974460a90540b045c102012da2492999557e6840526Jim Grosbach OS << "<vectorindex " << getVectorIndex() << ">"; 1975460a90540b045c102012da2492999557e6840526Jim Grosbach break; 1976fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1977fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 19783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 19793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 19803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 19813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 19823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 19833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 19843483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 19853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 198669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 198769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 19881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1989bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1990bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1991bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1992bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 19939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1994e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1995e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 19963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 19971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 199818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 19997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 2000d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 2001a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 2002a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 20030c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 20040c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 20050c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 20060c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 20070c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 20080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 20090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 20100c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 20110c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 20120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 20130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 20140c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 201569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 2016b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 2017460a90540b045c102012da2492999557e6840526Jim Grosbach 2018e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 2019e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 2020d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 202119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 202219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 202319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 202419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 202519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 20260d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 20270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 20280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 20290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 20300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 20310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 20320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 20330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 20340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 20350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 20360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 20370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 20380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 20390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 20400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 20410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 20420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 204319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 20440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2045e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 2046e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 2047e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 2048e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 2049e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 2050eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 2051e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 2052e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 2053e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 2054e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 2055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 2056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 2057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 2058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 2059e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 2060e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 2061e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 2062e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 2063e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2064e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 2065e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 2066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 206719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 206819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 206919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 207019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2071e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 2072e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 207319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 207419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 207519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 207619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2077e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 2078e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 2079e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 2080e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 2081e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 2082e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 2083e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 208419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 208519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 2086e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2087e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 20881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 2089e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 209019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 209119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 209219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 209319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 209419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 209519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 2096e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 209719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 209819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 2099e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 2100e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 210192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 210292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 2103af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 21040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 210592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 210692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 210792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 21080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 210919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 21100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 21110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 21120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 211350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 211450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 211550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 2116e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 2117e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 2118e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 211950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 21201355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2121e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 21221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 2123e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 212450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2125d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 212650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 2127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2128e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 2129e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 213050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 213150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 2132e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 2133460a90540b045c102012da2492999557e6840526Jim Grosbach return false; 2134460a90540b045c102012da2492999557e6840526Jim Grosbach } 2135460a90540b045c102012da2492999557e6840526Jim Grosbach 2136460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 2137460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 2138460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 2139460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 2140460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 2141460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 2142460a90540b045c102012da2492999557e6840526Jim Grosbach 2143460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 2144460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 2145460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2146460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2147460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 2148460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 2149460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2150460a90540b045c102012da2492999557e6840526Jim Grosbach } 2151460a90540b045c102012da2492999557e6840526Jim Grosbach 2152460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2153460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 2154460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 2155460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 2156460a90540b045c102012da2492999557e6840526Jim Grosbach } 2157460a90540b045c102012da2492999557e6840526Jim Grosbach 2158460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 2159460a90540b045c102012da2492999557e6840526Jim Grosbach 2160460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 2161460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 2162460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 216399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 216499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 216550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2166a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2167a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2168fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 2169fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 2170fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 2171fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 2172e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 2173e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 2174e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 2175e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 2176e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 2177fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 2178e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2179e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 2180e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2181e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 2182e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 2183e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 2184e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 2185e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 2186e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 2187e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 2188e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 2189e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 2190e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 2191e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2192e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2193e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 2194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 2195e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2196e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 2197e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 2198e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 2199e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 2200e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 2201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 2202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 2203e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 2204e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2205e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 2206e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 2207e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2208e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 2209e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2210e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 221189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 221289df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 221389df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 221489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 221589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 221689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 221789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 221889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 221989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 222089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 222189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 222289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 222389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 222489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 222589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 222689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 222789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 222889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 222989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 223089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 223189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 223289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 223389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 223489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 223589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 223689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 223789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 223889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 223989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 224089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 224189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 224289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 224389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 224489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 224589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 224643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2247fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2248fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2249f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 225043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2251e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 2252e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 2253c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2254c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2255e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2256fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2257e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 2258f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2259e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2260e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 2261fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2262f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2263fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 2264fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 226543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2266fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2267fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2268f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 226943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2270fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2271fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2272c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2273c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach return MatchOperand_NoMatch; 2274fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2275fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2276fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 2277f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2278fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2279fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2280fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2281f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2282e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2283e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 22849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 22859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}' 22869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 22879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc S = Parser.getTok().getLoc(); 22899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 22909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // If this isn't a '{', this isn't a coprocessor immediate operand. 22919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::LCurly)) 22929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_NoMatch; 22939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '{' 22949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 22959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCExpr *Expr; 22969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 22979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (getParser().ParseExpression(Expr)) { 22989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "illegal expression"); 22999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 23009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 23019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 23029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 23039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 23049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 23059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach } 23069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach int Val = CE->getValue(); 23079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 23089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach // Check for and consume the closing '}' 23099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 23109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_ParseFail; 23119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach SMLoc E = Parser.getTok().getLoc(); 23129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Parser.Lex(); // Eat the '}' 23139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 23149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 23159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach return MatchOperand_Success; 23169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach} 23179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach 2318d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 2319d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 2320d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 2321d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 2322d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 2323d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 2324d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 2325d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2326d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 2327d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 2328d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 2329d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2330d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2331d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2332d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2333d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2334d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2335d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2336d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2337d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2338d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 2339d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2340d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 234150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 23421355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 234318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 2344a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 2345e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 2346d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 2347d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 234816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2349d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 2350d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 2351d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 2352d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 2353d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 2354d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2355d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach MCRegisterClass *RC; 2356d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2357d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2358d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2359d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2360d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2361d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2362d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 2363d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2364e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 2365d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 2366d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // space for that many. 2367d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2368d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Store the first register. 2369d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2370d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2371d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 2372d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 2373d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 2374d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2375d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2376d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2377d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2378d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2379d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 2380d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2381d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2382d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2383d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2384d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2385d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2386d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2387d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2388d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2389d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2390d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2391d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2392d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2393d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2394d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2395d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2396d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2397d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2398d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2399d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2400d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2401d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2402d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2403d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2404d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 24052d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2406d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2407d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2408d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2409d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2410d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg)) 2411d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2412d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2413d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2414d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2415d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2416d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2417d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2418d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2419d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2420d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2421d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2422d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2423d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2424d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2425e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 242650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 242750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2428d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2429d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 2430862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list 2431862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2432862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2433862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if(Parser.getTok().isNot(AsmToken::LCurly)) 2434862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_NoMatch; 2435862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2436862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc S = Parser.getTok().getLoc(); 2437862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '{' token. 2438862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 2439862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2440862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int Reg = tryParseRegister(); 2441862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2442862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2443862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2444862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2445862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2446862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned FirstReg = Reg; 2447862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach unsigned Count = 1; 2448862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach while (Parser.getTok().is(AsmToken::Comma)) { 2449862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat the comma. 2450862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach RegLoc = Parser.getTok().getLoc(); 2451862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach int OldReg = Reg; 2452862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Reg = tryParseRegister(); 2453862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg == -1) { 2454862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "register expected"); 2455862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2456862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2457862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // vector register lists must also be contiguous. 2458862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // It's OK to use the enumeration values directly here rather, as the 2459862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach // VFP register classes have the enum sorted properly. 2460862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Reg != OldReg + 1) { 2461862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(RegLoc, "non-contiguous register range"); 2462862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2463862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2464862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2465862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach ++Count; 2466862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2467862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2468862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2469862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) { 2470862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Error(E, "'}' expected"); 2471862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_ParseFail; 2472862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach } 2473862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Parser.Lex(); // Eat '}' token. 2474862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 2475862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E)); 2476862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach return MatchOperand_Success; 2477862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach} 2478862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach 247943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2480f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 248143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2482706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2483706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2484706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2485706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 2486706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2487706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2488706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 2489706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 2490032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 2491706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 2492032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 2493706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 2494706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 2495032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 2496706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 2497032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 2498706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 2499706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 2500706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 2501706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2502706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 2503f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2504706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2505706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2506706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2507f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2508706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 2509706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 251043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2511a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 251243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2513a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2514a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 2517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 25182dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // An iflags string of "none" is interpreted to mean that none of the AIF 25192dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // bits are set. Not a terribly useful instruction, but a valid encoding. 2520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 25212dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (IFlagsStr != "none") { 25222dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 25232dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 25242dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("a", ARM_PROC::A) 25252dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("i", ARM_PROC::I) 25262dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("f", ARM_PROC::F) 25272dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Default(~0U); 25282dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 25292dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // If some specific iflag is already set, it means that some letter is 25302dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // present more than once, this is not acceptable. 25312dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (Flag == ~0U || (IFlags & Flag)) 25322dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson return MatchOperand_NoMatch; 25332dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 25342dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson IFlags |= Flag; 25352dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson } 2536a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2537a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2538a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2539a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2540a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 2541584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 2542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 254343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2544584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 254543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2549584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 2550584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2551acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 2552acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 2553acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2554acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 2555acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 2556acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 2557acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 2558acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 2559acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 2560acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 2561acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 2562acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 2563acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 2564acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 2565acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 2566acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 2567acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 2568acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 2569acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2570acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 2571acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2572acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2573acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 2574acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 2575acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2576acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2577acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 2578acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2579acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 2580acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 2581acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2582584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 2583584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 2584584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 2585b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 2586584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 2587584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 2588584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2589584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 2590584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 2591584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2592584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 2593584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2594584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 2595584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 2596b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 2597584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 2598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 2599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2600584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 26014b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 2602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 2603584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2604584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 2605bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 26064b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 2607584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 260856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 260956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 2610584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 2611584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 2612584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 2613584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 2614584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 2615584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 2616584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2617584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2618584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 2619584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 2620584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 2621584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2622584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 2623584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2624584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 2625584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2626584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 26277784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // Special register without flags is NOT equivalent to "fc" flags. 26287784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // NOTE: This is a divergence from gas' behavior. Uncommenting the following 26297784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // two lines would enable gas compatibility at the expense of breaking 26307784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // round-tripping. 26317784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // 26327784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // if (!FlagsVal) 26337784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson // FlagsVal = 0x9; 2634584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2635584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2636584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 2637584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 2638584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2639584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2640584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2641584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 2642a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 2643a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2644f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2645f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 2646f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 2647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2648f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2649f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2650f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2651f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2652f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 2653f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 2654f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 2655f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 2656f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2657f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2658f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2659f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 2660f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2661f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 2662f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2663f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2664f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2665f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2666f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 2667f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2668f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 2669f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 2670f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2671f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 2672f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2673f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2674f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2675f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 2676f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 2677f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2678f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2679f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 2680f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 2681f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 2682f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2683f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2684f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2685f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 2686f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2687f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 2688f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 2689f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2690c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2691c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2692c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2693c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 2694c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2695c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2696c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2697c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2698c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 2699c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 2700c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 2701c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 2702c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 2703c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2704c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 2705c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2706c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2707c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2708c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 2709c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 2710c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 2711c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 2712c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 2713c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2714580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 2715580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 2716580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 2717580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 2718580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 2719580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2720580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2721580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 2722580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 2723580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2724580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2725580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2726580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2727580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 2728580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 2729580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 2730580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 2731580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 2732580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 2733580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 2734580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2735580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2736580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2737580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 2738580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2739580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 2740580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2741580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2742580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2743580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2744580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 2745580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2746580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 2747580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2748580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2749580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 2750580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2751580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2752580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2753580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 2754580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 2755580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2756580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2757580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2758580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 2759580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 2760580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2761580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 2762580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 2763580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2764580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 27650afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 27660afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 27670afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 27680afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 27690afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 2770580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 2771580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 2772580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2773580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 2774580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 2775580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2776580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2777580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2778580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2779580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 2780580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 2781580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2782580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 2783580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 2784580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 27857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 27867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 27877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 27887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 27897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 27907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 27917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 2792326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2793326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 27947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 2795326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 2796326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 27977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 27987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 27997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 28007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 28017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 28027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 28037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 28047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 28057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 28067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 28077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 28087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 28097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 28107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 28117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 28127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 28137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 28147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 28157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 28167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 28177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 28187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 28197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 28207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 28217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 28227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 28237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 28247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 28257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 28267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 28277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 28287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 28297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 28307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 28317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 28327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2833293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2834293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2835293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2836293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2837293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2838293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2839293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2840293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2841293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2842293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2843293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2844293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2845293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2846293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2847293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2848293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2849293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2850293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2851293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2852293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2853293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2854293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2855293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2856293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2857293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2858293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2859293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2860293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2861293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2862293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2863293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2864293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2865293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2866293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2867293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2868293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2869293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2870293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2871293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2872293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2873293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2874293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2875293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2876293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2877293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2878293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2879293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2880293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2881293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2882293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2883293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2884293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2885293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2886293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2887293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2888293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2889293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2890293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2891293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2892293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2893293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2894293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2895293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2896293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2897293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2898293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 28997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 29007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 29017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2902f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2903f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2904f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 29057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 29067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 29077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 29087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 29097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 29107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 29117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 291216578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 29137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 29147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 29157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 29167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 29177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 29187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 291916578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 29207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 29217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 29227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 29237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 29247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 29257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 29267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 29277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 29287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 29297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 29307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 29317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2932f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2933f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 29340d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 29350d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 29360d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 29370d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 29380d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2939f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2940f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2941f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 29427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 29437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 29447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 29457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2946251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2947251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2948251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2949251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2950251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2951251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2952251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2953251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2954251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2955251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2956251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2957251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2958251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2959251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2960251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2961251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2962251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2963251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2964251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2965251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2966251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2967251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2968251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2969251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2970251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2971251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2972251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2973251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2974251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2975251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2976251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2977251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2978251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2979251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2980251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2981251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2982251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2983251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2984251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2985251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2986251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2987251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2988251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2989251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2990251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2991251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2992251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2993251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2994251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2995251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2996251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2997251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2998251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2999251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3000251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 3001251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 3002251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 3003251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 3004251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 3005251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 3006251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 3007251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 3008251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 3009251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3010251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 3011251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 3012251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3013251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 3014251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 3015251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 3016a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 3017a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3018a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3019a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3020a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 3021a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3022a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3023a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3024a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3025a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3026a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3027a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3028a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3029a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3030a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3031a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3032a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3033a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3034a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 3035a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3036a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3037a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 3038a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 3039a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3040a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 3041a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 3042a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 3043a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3044a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3045a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 3046a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 3047a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 3048a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3049a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 3050a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 3051a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 3052eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3053eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3054eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3055eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 3056eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3057eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3058eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3059eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3060eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 3061eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3062eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3063eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3064eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3065eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 3066eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 3067eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 3068ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 3069ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3070ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3071ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 3072ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 3073ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3074ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 3075ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3076ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3077ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 3078ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3079ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 3080ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 3081ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 30821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3083ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3084ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3085ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 30861355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3087ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3088ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3089ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 3090ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3091ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3092ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 30937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3094ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3095ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3096ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3097ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 30989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 30999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 31009ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 31019ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 31029ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 31039ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31049ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 31059ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 31069ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 31079ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 31089ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 31099ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 31109ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 31119ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 31129ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 31139ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 31149ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 3115548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 3116548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3117548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3118548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 3119548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 3120548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3121548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 3122548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3123548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3124548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 3125548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3126548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 3127548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 3128548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 31291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 3130ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 31331355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 3134ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3135ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 3136ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 3137548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3138548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 3139548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 31407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 31417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 31427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 31437b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 31447b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 31457b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 31467b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 31477b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 31487b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31497b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 31507b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 31517b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 31527b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 31537b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 31547b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 31557b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 31567b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 31577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 31587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 31597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 31607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 31617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 31627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3164ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 31657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 31667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 31677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 31687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 31697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 31707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 31717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3172ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3173ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 3174ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 3175ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 31767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 3177ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3178ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3179ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 31807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 31817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3183aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3184ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3185ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 31867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 31877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 31887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 31897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 31907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 31917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 31927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 31937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 3194aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 31957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 31967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 31977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 31987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 31997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 32007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 32027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 32037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 32047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 32057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 32067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 32077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 32087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 32097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3210ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3211ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3212ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3213ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 32147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 3215ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3216ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 3217ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 32187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 32197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3220ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 3221ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 32227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 3223ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 32247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 32257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 32267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 32277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 32287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 3229ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3230ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 3231ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 3232ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 32332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 32342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 32352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 32362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 32372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 32382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 32402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 32412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 32422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 32432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 32442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 32452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 32462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 32472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 32482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 32492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 32502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 325114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 325214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 325314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 325414605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 325514605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 325614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 325714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 325814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 325914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 326014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 326114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 326214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 326314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 326414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 326514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 326614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 326714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 326814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 3269623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 3270623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3271623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 3272623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 3273623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 3274623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3275623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3276623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 3277623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 3278623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 3279623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3280623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 3281623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 3282623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 328388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 328488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 328588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 328688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 328788ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 328888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 328988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 329088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 329188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 32927a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 32937a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 32947a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 32957a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 329688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 32977a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 329888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 329988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 330088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 330188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 330288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 33037a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // If we have a three-operand form, use that, else the second source operand 33047a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // is just the destination operand again. 33057a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach if (Operands.size() == 6) 33067a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 33077a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach else 33087a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach Inst.addOperand(Inst.getOperand(0)); 330988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 331088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 331188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 331288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 3313623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 3314e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 33159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 331650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 33177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3318762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 331918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3320a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 3321762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3322b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 3323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 332418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 33251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 33267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 33277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 3328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 33290571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 33300571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 33310571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 33327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 33330571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 33347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 3335762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 3336b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 3337a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 33387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 333957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 0, 0, false, S, E)); 334003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 3341fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3342fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 3343fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3344fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3345fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 3346fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 3347fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 33487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 33497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 335050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 33517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 33527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 335350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 335457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a ':', it's an alignment specifier. 335557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Colon)) { 335657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the ':'. 335757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 335857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 335957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCExpr *Expr; 336057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (getParser().ParseExpression(Expr)) 336157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return true; 336257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 336357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // The expression has to be a constant. Memory references with relocations 336457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // don't come through here, as they use the <label> forms of the relevant 336557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // instructions. 336657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 336757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!CE) 336857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error (E, "constant expression expected"); 336957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 337057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Align = 0; 337157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach switch (CE->getValue()) { 337257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach default: 337357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "alignment specifier must be 64, 128, or 256 bits"); 337457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 64: Align = 8; break; 337557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 128: Align = 16; break; 337657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 256: Align = 32; break; 337757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 337857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 337957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Now we should have the closing ']' 338057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 338157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 338257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "']' expected"); 338357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat right bracket token. 338457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 338557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Don't worry about range checking the value here. That's handled by 338657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // the is*() predicates. 338757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 338857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, Align, 338957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 339057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 339157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 339257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // operand. 339357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 339457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 339557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the '!'. 339657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 339757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 339857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return false; 339957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 340057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 340157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a '#', it's an immediate offset, else assume it's a register 34027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 34037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 34047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 34057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 340650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 34070da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 34087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 34097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 34107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 341105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 34127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 34137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 34147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 34157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 34167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 34177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 34187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 34190da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 34200da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 34210da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 34220da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 34230da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 34247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 34257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 34267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 34277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 34287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 342905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 34307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 34317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 34327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 343357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, 0, 343457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 3435a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 34367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 34377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 34387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 34397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 34407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 3441762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 34427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 34437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 34449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 3445d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 34467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 34477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 34487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 34497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 34507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 34517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 34527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 34537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 34547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 34559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 34567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 34577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 34587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 34597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 34607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 34617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 34627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 34630d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 34647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 34657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 34660d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 34677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 34689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 346916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 34707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 34717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 34727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 34737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 34747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 34757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 34767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 347757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ShiftType, ShiftImm, 0, isNegative, 34787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 34797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3480f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3481f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 3482f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3483f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3484f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 3485f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 34869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 34879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 34889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 34899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 34907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 3491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 3492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 34937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 34947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 34957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 34967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 349718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3498a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3499a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 350038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 3501a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 35020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 3503a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 35040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 3505a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 35060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 3507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 35080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 3509a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 35100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 3511a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 35127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 3513b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 3514a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 35157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 35167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 35177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 35187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 35197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 35207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 35217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 35227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 35237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 35249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 35257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 35267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 35277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 35287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 35297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 35307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 35317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 35327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 35337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 35347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 35357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 35367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 35377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 35387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 35397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 35407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 3541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 3543a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 35459d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 35469d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 35479d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 35489d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 35499d39036f62674606565217a10db28171b9594bc7Jim Grosbach 35509d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) 35519d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 35520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 35530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // Disambiguate the VMOV forms that can accept an FP immediate. 35540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <sreg>, #imm 35550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f64 <dreg>, #imm 35560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <dreg>, #imm @ vector f32x2 35570e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.f32 <qreg>, #imm @ vector f32x4 35580e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // 35590e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // There are also the NEON VMOV instructions which expect an 35600e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // integer constant. Make sure we don't try to parse an FPImm 35610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // for these: 35620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach // vmov.i{8|16|32|64} <dreg|qreg>, #imm 35630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]); 35640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach if (!TyOp->isToken() || (TyOp->getToken() != ".f32" && 35650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach TyOp->getToken() != ".f64")) 35660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach return MatchOperand_NoMatch; 35670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach 35689d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 35699d39036f62674606565217a10db28171b9594bc7Jim Grosbach 35709d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 35719d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 35729d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 35739d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 35749d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 35759d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35769d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 35779d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 35789d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 35799d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 35809d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 35819d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 35829d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 35839d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 35849d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 35859d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 35869d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 35879d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35889d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 35899d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 35909d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35919d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 35929d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 35939d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 35949d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 35959d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 35969d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 35979d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 35989d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 35999d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 36009d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 36019d39036f62674606565217a10db28171b9594bc7Jim Grosbach 36029d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 36039d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 36049d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 36059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 36069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 36071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3608fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 3609762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 3610fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3611fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 3612fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 3613f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 3614f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 3615fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 3616f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 3617f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 3618f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 3619f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 3620f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 3621fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 3623146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 3624146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 362550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 362619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 36275cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 36281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 362950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 36300d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 363119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 36320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 363319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 363419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 36355cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 36365cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 36375cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 36385cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 36395cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 36405cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 3641e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 3642e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 3643e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 364419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 364567b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 364667b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 3647515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 3648515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 3649515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 3650762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3651515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 365250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 3653762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 365450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 365550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 365650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 3657a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 36581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 3659d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 36601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 366163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 3662079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 3663079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 3664762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3665b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 366663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 3667515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 3668515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 366950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 367063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 367163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (!CE) { 367263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson Error(S, "constant expression expected"); 367363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return MatchOperand_ParseFail; 367463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 367563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson int32_t Val = CE->getValue(); 367663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (isNegative && Val == 0) 367763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 3678762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 367950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 368050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 368163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 36829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 36839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 36847597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 36857597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 36867597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 36871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 36889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 36899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 36907597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 36917597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 36929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 36939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 36947597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 36957597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 36969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 36977597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 36989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 36999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 3700a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3701a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3702a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 37031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 37047597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 37051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 37067597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 37079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 37089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 37098a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 37109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 37119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 37129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 37139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 37149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 37159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 37169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 37179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 37189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 37197597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 37209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 37217597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 37229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 37239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 37249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 37259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 37269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 37279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 37289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 37299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 37309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 37319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 37329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 37339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 37349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 37359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 3736352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 3737352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 3738352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 3739badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 374089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 37411355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 37425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 37435f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 374489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 374589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 3746352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 3747352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 3748a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 3749352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3750badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 3751352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 3752352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 37535f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 37545f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 37555f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 37565f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 37575f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 37585f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 37595f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 37605f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 3761352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3762badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 37633f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 37643f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 3765ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 376671725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 376704d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 37682f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 37693f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 37703f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 37713f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 37723f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 37733f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 37743f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 37753f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 37763f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 37773f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 37783f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 37793f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 37803f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 37813f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 37823f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 37833f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 37843f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 37853f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 37863f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 37873f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 37883f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 37893f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 37903f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 37913f00e317064560ad11168d22030416d853829f6eJim Grosbach } 379252925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 3793345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3794352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 3795352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 3796352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 379700f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 37985f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 37995f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 38005f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 3801e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 3802e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 3803352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 3804352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 3805352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 3806352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 3808a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 3809a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 3810a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 3811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 3812a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 3813a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 3814a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 3815a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 3816a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 3817a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 3818a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 3819a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3820a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3821a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 382289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 382389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 382489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 382589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 382689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 382789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3828352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3829352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 38303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 38313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 38323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 38333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 38343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 3835fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 38361355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 3837fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 3838eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 3839eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 38403443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 3841eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 3842d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 3843eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 3844d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 38453443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 3846d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 3847d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 3848eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 3849fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 3850eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 38513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 3852eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 3853eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 3854eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 3855eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 3856ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 3857ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 38580780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 38592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" || 38602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "ldc2" || Mnemonic == "ldc2l" || 38612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) || 38624af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 38634af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 38641ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 38653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 3866fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 38673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 3868fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 3869fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 3870fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 387163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 3872fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 3873fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 3874badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 3875badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3876d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 3877d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 387820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 387920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 3880d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3881d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 3882d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 3883d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 3884d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 3885d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 3886d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 3887d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 3888d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 38898adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 3890d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 3891d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 3892d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3893d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 38943912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 38953912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 38963912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 38973912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 38983912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 38993912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 39003912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 39013912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 390272f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 390320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 390420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 390520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 3906f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 3907f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 3908f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 390972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 391072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 391172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 391220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 391320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 391420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 391572f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 3916f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 3917f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 391820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 391920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 392020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 3921f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 3922f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 392320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 392420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 392520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 392620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 392720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 392820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 392920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 393020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 393120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 393220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 393320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 393420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 393520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 393620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 393720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 393864944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 393920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 394020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 394120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 394220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 394320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 394420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 394520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 394620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 394720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 394864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 394964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 395064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 395164944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 395264944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 395364944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 395464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 395564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 395664944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 395764944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 395864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 395964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 396064944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 396164944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 396264944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 396364944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 396464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 396564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 396664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 396764944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 396864944f48a1164c02c15ca423a53919682a89074cJim Grosbach 396964944f48a1164c02c15ca423a53919682a89074cJim Grosbach 397020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 3971f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 3972f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 3973f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 3974f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 3975f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 3976f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 3977f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 397872f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 397972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 398072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 398172f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 39823912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 3983d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 3984d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 3985d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3986badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 3987badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 3988badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3989badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 3990badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 3991ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 3992badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3993352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 3994352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 3995a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 3996352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 399789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 39981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 399989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 4000badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 40010c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 40020c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 40030c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 40040c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 40050c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 40060c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 4007ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 4008ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 400989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 401089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 401189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 401289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 401389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 401489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 4015f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 4016f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 4017f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 4018f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 4019f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 402089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 402189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 402289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 402389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 402489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 4025f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 402689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 402789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 402889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 402989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 403089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4031f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 403289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 403389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 4034ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 4035ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 40369717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 40373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 40383771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 40393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 40403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 40413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 40423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 40433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 40443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 40451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 40463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 404733c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 404833c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 404933c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 405033c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 4051ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 405233c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 405333c16a27370939de39679245c3dff72383c210bdJim Grosbach } 4054c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 4055c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 4056c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 4057c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 4058c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 4059c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 4060c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 406133c16a27370939de39679245c3dff72383c210bdJim Grosbach 40623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 4063f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 4064f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 40653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 4066f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 4067f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 40683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 40693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 40703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 4071f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 4072f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 40733771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 4074f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 4075badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 4076345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 4077a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 4078a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 4079a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 4080a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 4081a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 4082a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 4083a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 4084345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 40855747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 40865747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 40875747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 4088a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 4089a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40904d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // For now, we're only parsing Thumb1 (for the most part), so 40914d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // just ignore ".n" qualifiers. We'll use them to restrict 40924d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // matching when we do Thumb2. 409381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 409481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 409581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 409681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 40975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 40985747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 40995747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 41005747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 4101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 41021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4103cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4104cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4105cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4107a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 4108b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 4109a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4110a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 41111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 4112cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4113cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 4114cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4115a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 4116a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 411716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4118cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 4119186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach SMLoc Loc = getLexer().getLoc(); 4120cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 4121186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach return Error(Loc, "unexpected token in argument list"); 4122cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 4123146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 412434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 4125ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4126d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 4127d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 4128d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 412920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 413020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 413120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 413220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 413320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 4134ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4135ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 4136ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 4137ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 4138ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 4139cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 4140cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 4141cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 414221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // a k_CondCode operand in the list. If we're trying to match the label 414321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // version, remove the k_CondCode operand here. 4144cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 4145cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 4146cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 4147cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 4148cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 4149cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 4150857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 4151857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 4152857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 4153857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 4154857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 4155857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 4156857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4157857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4158857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4159857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 4160857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 4161857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 416268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 416368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 416468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 416568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 416668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 416768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 416868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 416968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 417068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 417168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 417268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4173857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 4174857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4175857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 4176934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 4177934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 4178934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 4179934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 4180934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 4181934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 4182934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 4183934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 4184934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 4185934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 4186934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4187934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 4188934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 41899898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 4190ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4191ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4192189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 4193aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 4194aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 4195aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 4196aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 4197aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 4198aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 4199aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 4200aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 4201aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 4202aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 4203aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 4204aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 4205aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 4206aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 4207aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 4208aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 4209aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 4210aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 421176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 421276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 421376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 421476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 421576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 421676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 421776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 421876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 421976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 422076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 422176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 4222f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 4223f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 4224f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 4225f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 4226f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[]; 4227f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 4228f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 4229f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 4230f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 4231f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4232189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 4233189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 4234189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 4235189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 4237f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 4238f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 4239b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 4240b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 4241b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 4242b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 4243f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 4244f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 4245f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 4246f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 4247a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 4248f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 4249f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 4250f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 4251f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 4252f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 4253f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 4254f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 4255f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 4256f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 4257f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 4258f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 4259f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 4260f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 4261f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 4262f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 4263f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 4264f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 4265c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 4266f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 4267f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 426851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 426951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 4270f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 4271f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4272189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 42732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 42742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 42752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 4276189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 4277189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4278189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 4279189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4280189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 4281189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 4282189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 4283189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4284189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 428514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 428614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 428714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 428814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 428914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 429014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 429114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 429214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 429314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 429453642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 429553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 4296189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 4297189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 4298189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4299189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 4300189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 430114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 4302189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 4303189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4304189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4305fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 4306fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 4307fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 4308fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 4309fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 4310fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 4311fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 4312fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 431300c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 4314fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 431593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 431676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 431776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 431876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 431976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 432076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 432193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 432293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 432393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 43247260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 43257260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 43267260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 4327aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 432876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 4329aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 4330aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 433193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 433276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 433393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 433493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 433576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 433676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 4337aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 43387260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 43397260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 43407260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 434193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 434293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 434393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 434476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 434576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 434676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 434776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 434876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 434976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 435076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 43516dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 4352aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 4353aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 4354aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4355aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 43566dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 43576dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 43586dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 4359aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 4360aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 4361aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4362aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 43636dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 43646dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 43651e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 43661e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 43678213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 43681e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 43691e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 43701e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 43711e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 4372189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4373189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4374189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4375189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 4376189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4377f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 4378f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 4379f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4380f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 4381f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 4382f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 4383f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 4384f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 4385f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 4386f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 4387f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 4388f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4389f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4390f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 4391f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 4392f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 4393f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4394f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4395f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 4396f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4397f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 4398f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 4399f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 4400f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 4401f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 4402f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 4403f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 4404f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 4405f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4406f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4407f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 4408f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 4409f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4410f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4411f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 4412f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 4413f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 441489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 44150f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 44160f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 44170f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 44180f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 44190f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 442089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 442189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 4422f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 4423f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 4424f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 4425f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 4426f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 4427f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 4428f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 4429f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 443051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 443151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 443251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 443351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 443451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 443551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 443651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 443751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 443851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 443951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 4440c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 4441a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 4442a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) 4443c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 4444c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 4445395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 4446395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 4447395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) 4448395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 44493ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 445076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 445176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 445276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 445376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 445476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 445576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 445676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 445776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 445876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 445976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 446076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 446176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 446276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 446376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 446476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 446576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 446676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 446776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 446876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 446976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 447076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 447176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 447276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 447376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 44748213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 44758213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 44768213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 44778213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 44788213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 44798213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 44808213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 44818213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 44828213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 44838213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 44848213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 44858213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 44868213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 44871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 44881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 44891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 44901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 44911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 4492c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 4493c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 4494c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 44951ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 44961ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 44971ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 44981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 44991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 45001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 45011ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 45021ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 45031ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 45041ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 45051ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 45061ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 45071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 45081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 45091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 45101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 45111ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 45121ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 45131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 45141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 45151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 45161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 45171ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 45181ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 45191ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 45201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 45211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 45221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 45231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 45241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 45251ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 45261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 45271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 45281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 4529326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 453050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 453150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 453250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 4533326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 4534326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 4535326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4536326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4537326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 4538326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4539326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 454050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 454150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 454250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 454350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 454450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 454550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 454650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 454750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 4548326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 4549326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 4550326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 4551326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 4552326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 4553326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4554326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 4555326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 4556326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 4557326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 4558326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 455989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 456089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 456189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 456289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 456389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 456489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 456589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 456689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 456789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 4568f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 4569f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 457089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 457189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 457289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 457389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 457489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 457589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 457689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 4577f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4578f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 4579f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 4580f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 4581f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 4582f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 4583f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 4584f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 458589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 458689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4587f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4588f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 4589f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 459047a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 459147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 459247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 4593194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 4594194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 459547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 459647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 459747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 459847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 459947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 460047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 460147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 460247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 460347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 460447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 460547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 460647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 460747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 460847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 460947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 461047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 4611f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 4612f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 461347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 4614f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 4615f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 4616f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 461747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 4618194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 4619194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 4620194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 4621194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4622194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 4623194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 4624194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 46254ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 4626194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 4627194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 4628194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 462947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 463047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 463147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 4632fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 4633fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 4634fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4635fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 4636fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 4637fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 463819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 4639193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 4640193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 464119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 4642e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 4643189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 4644189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 4645a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 4646a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 4647a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 4648a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4649189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 4650a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 4651189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4652f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 4653f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 4654f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 4655f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 4656a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 4657a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 4658a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 4659a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4660a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 4661fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 4662fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 4663e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 4664e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 4665e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 4666e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 4667e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 4668e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 4669e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 4670e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 467116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4672e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 4673e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 4674e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 467516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4676e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 4677e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 4678e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 467947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 4680b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 468188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 468288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 4683f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 4684f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 468547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 468647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 4687194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 4688194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 4689194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 4690194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 4691fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 469216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4693c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 4694146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 4695fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 4696fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 46971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 4698ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 4699ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 4700ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 47011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 4702515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 47031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 4704515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 47051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 4706515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 47071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 4708515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 47091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 4710ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4711ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4712ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 4714ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 47151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 4716ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 4717ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 4718ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 4719ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 4720ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4721ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4722aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 4723ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4724ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 4725ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 472616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4727ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 4728ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 4729ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 4730b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4731ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4732ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4733ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4734b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4735ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 4736ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4737ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 4739515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 47401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 4741515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4742515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4743b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4744515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4745515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 4746515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 4747515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4748515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4749515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4750515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 47511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 4752515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 47531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 47546469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 47556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 47566469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 47576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 47586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 47596469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 47606469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 47616469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 47626469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 47636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 47646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 47656469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 47666469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 47676469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4768515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4769515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4770b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 47726469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 47736469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 47746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 47756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 47766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4777642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 4778642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 4779642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 4780515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4781515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4782515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 47831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 4784515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 47851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 478618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4787515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 4788515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 478938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 479058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 4791b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 479258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 47939e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 4794515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 4796515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4797515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 479818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4799b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4800515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4801515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 4802515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4803515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4804515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4805515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 48061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 4807515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 48081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 480918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4810515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 4811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 481218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 481358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 4814b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 481558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 4816b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4817515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4818515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 4819515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4820515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 482118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4822b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4823515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 482432869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 482598447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 4826ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 482798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 482832869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 482998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 4830ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 483198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 4832eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 48332a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 4834515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4835515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4836515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 483790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 483890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 48399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 4840ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 484194b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 484294b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 484390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 4844ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 48453483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 48460692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 48470692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 48483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 4849