ARMAsmParser.cpp revision 57dcb85a30133a9bc008f0b9ead81be03a23521e
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*>&); 14143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1428bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1448bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1468bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 147f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 148f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 149f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 150f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 155c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 156580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 158293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 160251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 1619d39036f62674606565217a10db28171b9594bc7Jim Grosbach OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 162ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 163ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 164a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 165a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 166a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 167a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 168eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 169eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 170ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 171ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 173ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1749ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 1759ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &); 176548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 177548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 179ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1807b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1817b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 19314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 194623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 195623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 19788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 198189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 199189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 200189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 201f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach void processInstruction(MCInst &Inst, 202f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 203d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 204d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 205189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 206ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 20747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 208194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 209f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Match_RequiresNotITBlock, 210194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 211194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 21247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 21347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 214ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 21594b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 216ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 21732869205052430f45d598fba25ab878d8b29da2dEvan Cheng 218ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 219ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 220f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 221f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Not in an ITBlock to start with. 222f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = ~0U; 223ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 224ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 2261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 2271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 228189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 2291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 2301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 23147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 23247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 2331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 2341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 236ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 23716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 23816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 2403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 243146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 24521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CondCode, 24621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CCOut, 24721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ITCondMask, 24821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocNum, 24921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocReg, 25021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Immediate, 25121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_FPImmediate, 25221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MemBarrierOpt, 25321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Memory, 25421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_PostIndexRegister, 25521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MSRMask, 25621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ProcIFlags, 257460a90540b045c102012da2492999557e6840526Jim Grosbach k_VectorIndex, 25821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Register, 25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RegisterList, 26021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_DPRRegisterList, 26121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_SPRRegisterList, 26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedRegister, 26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedImmediate, 26421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShifterImmediate, 26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RotateImmediate, 26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_BitfieldDescriptor, 26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Token 268a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 269a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 27124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2758462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2768462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 279fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 280fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 281fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 282fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 28389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 28489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 28589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 28689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 28789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 28889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 28989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 29089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 291a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 292a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 293a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 294a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 298584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 299a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3078155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 308460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned Val; 309460a90540b045c102012da2492999557e6840526Jim Grosbach } VectorIndex; 310460a90540b045c102012da2492999557e6840526Jim Grosbach 311460a90540b045c102012da2492999557e6840526Jim Grosbach struct { 312cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 313cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 31416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3159d39036f62674606565217a10db28171b9594bc7Jim Grosbach struct { 3169d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned Val; // encoded 8-bit representation 3179d39036f62674606565217a10db28171b9594bc7Jim Grosbach } FPImm; 3189d39036f62674606565217a10db28171b9594bc7Jim Grosbach 3196a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 3227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 3237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 3247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 3257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 3267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 32757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned ShiftImm; // shift for OffsetReg. 32857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment; // 0 = no alignment specified 32957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // n = alignment in bytes (8, 16, or 32) 3307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 331e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach } Memory; 3320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 3330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 3347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 335f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 336f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 337f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 3387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 3397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 341580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 342e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 343580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 344e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 345e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 346e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 347e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 348e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 349af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 35092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 35192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 35292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 35392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 354af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 3557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 3567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 358293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 359293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 360293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 361293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 362a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 36316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 364146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 365146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 366762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 367762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 368762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 369762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 370762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 37121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 3728462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3738462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 37421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: 37589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 37689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 37721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 3788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 379762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 38021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 38121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 382762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 383762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 38421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 38521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 38621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: 38724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 3888d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 38921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 39021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 391fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 392fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 39321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 394762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 395762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 39621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 3979d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImm = o.FPImm; 3989d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 39921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 400706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 401706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 40221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 403e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory = o.Memory; 404762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 40521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 4067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 4077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 40821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 409584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 410584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 41121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: 412a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 4130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 415580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 4160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 418af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 419e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 42021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 421af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 42292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 42321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 4247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 4257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 42621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 427293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 428293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 429460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 430460a90540b045c102012da2492999557e6840526Jim Grosbach VectorIndex = o.VectorIndex; 431460a90540b045c102012da2492999557e6840526Jim Grosbach break; 432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 433762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 43416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 435762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 436762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 437762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 438762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 439a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4408462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 44121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_CondCode && "Invalid access!"); 4428462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 4438462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4448462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 445fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 44621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 447fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 448fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 449fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 450a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 45121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Token && "Invalid access!"); 452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 453a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 454a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 455a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 45621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 4577729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 458a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 459a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4605fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 46121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 46221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind == k_SPRRegisterList) && "Invalid access!"); 46324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 4648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 4658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 466cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 46721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Immediate && "Invalid access!"); 468cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 469cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 470cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 4719d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned getFPImm() const { 47221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_FPImmediate && "Invalid access!"); 4739d39036f62674606565217a10db28171b9594bc7Jim Grosbach return FPImm.Val; 4749d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 4759d39036f62674606565217a10db28171b9594bc7Jim Grosbach 476460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned getVectorIndex() const { 477460a90540b045c102012da2492999557e6840526Jim Grosbach assert(Kind == k_VectorIndex && "Invalid access!"); 478460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val; 479460a90540b045c102012da2492999557e6840526Jim Grosbach } 480460a90540b045c102012da2492999557e6840526Jim Grosbach 481706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 48221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MemBarrierOpt && "Invalid access!"); 483706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 484706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 485706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 486a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 48721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_ProcIFlags && "Invalid access!"); 488a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 489a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 490a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 491584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 49221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MSRMask && "Invalid access!"); 493584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 494584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 495584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 49621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocNum() const { return Kind == k_CoprocNum; } 49721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocReg() const { return Kind == k_CoprocReg; } 49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCondCode() const { return Kind == k_CondCode; } 49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCCOut() const { return Kind == k_CCOut; } 50021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITMask() const { return Kind == k_ITCondMask; } 50121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITCondCode() const { return Kind == k_CondCode; } 50221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isImm() const { return Kind == k_Immediate; } 50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isFPImm() const { return Kind == k_FPImmediate; } 504a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isImm8s4() const { 50521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 506a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 507a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 508a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!CE) return false; 509a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Value = CE->getValue(); 510a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 511a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 51272f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 51321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 51472f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 51572f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 51672f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 51772f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 51872f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 51972f39f8436848885176943b0ba985a7171145423Jim Grosbach } 52072f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 52121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 52272f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 52372f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 52472f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 52572f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 52672f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 52772f39f8436848885176943b0ba985a7171145423Jim Grosbach } 5286b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5306b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 5356b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 53683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 53721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 53883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 53983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 54083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 54183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 54283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 54383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 54483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 54521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 54683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 54783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 54883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 54983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 55083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 55183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 5527c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 55321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5547c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 5557c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5567c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 5577c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 5587c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 5597c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 560f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 56121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 562f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 563f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 564f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 565f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 566f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 567f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 5684a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 56921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5704a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 5714a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5724a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 5734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 5744a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 5754a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 576fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 57721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 578fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 579fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 580fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 581fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 582fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 583fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 584ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 58521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 586ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 587ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 588ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 589ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 590ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 591ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 592ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 593ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 594ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 59521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 596ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 597ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 598ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 599ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 600ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 601ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 60270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 60321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 60470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 60570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 60670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 60770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 60870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 60970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 610f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 61121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 612f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 613f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 614f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 615f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 616f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 617f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 618f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 61921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 620f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 621f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 622f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 623f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 624f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 625f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 6266bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 62721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6286bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 6296bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6306bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 6316bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 6326bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 6336bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 6346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 63521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6366b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 6376b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6386b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 6396b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 6406b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 6416b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 642c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 64321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 644c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 645c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 646c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 647c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 648c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 649c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 65021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isReg() const { return Kind == k_Register; } 65121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegList() const { return Kind == k_RegisterList; } 65221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 65321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 65421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isToken() const { return Kind == k_Token; } 65521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 65621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemory() const { return Kind == k_Memory; } 65721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isShifterImm() const { return Kind == k_ShifterImmediate; } 65821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 65921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 66021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRotImm() const { return Kind == k_RotateImmediate; } 66121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 66221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 663f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 66421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 665f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 66657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isMemNoOffset(bool alignOK = false) const { 667f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 668ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 6697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 67057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 && 67157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach (alignOK || Memory.Alignment == 0); 67257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 67357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach bool isAlignedMemory() const { 67457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return isMemNoOffset(true); 675ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 6767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 67757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 6787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 679e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 6807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 681e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 682e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 6837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 6847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 685039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 68621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 687039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 688039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 689039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 690039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 691039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 692039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 693039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 6942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 69557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 6962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 697e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::no_shift) return false; 6982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 699e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return true; 7002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 701e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 702e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 7032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 7042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 70621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate && Kind != k_PostIndexRegister) 7072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 70821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) 7092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 7102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 7112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 7132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 714251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 715251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 7162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 71857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.Alignment != 0) return false; 7197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 720e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.OffsetRegNum) return false; 7217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 722e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 723e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 7240da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 7250da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson Val == INT32_MIN; 7267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 7277f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBB() const { 728e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 72957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 7307f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7317f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7327f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7337f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBH() const { 734e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 73557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 73657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0 ) 7377f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7387f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7397f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 74157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0) 742ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 743ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 744ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 745ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach bool isT2MemRegOffset() const { 74657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 74757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.Alignment != 0) 748ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 749ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach // Only lsl #{0, 1, 2, 3} allowed. 750e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType == ARM_AM::no_shift) 751ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 752e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 753ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 754ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 755ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 7567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 7577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 7587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 759e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 76057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 76187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 762e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach return isARMLowRegister(Memory.BaseRegNum) && 763e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 76460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 76560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 766e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 76757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 76860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 76960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 770e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 771e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 772ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 773ecd858968384be029574d845eb098d357049e02eJim Grosbach } 77438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 775e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 77657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 77738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 77838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 779e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 780e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 78138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 78238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 78348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 784e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 78557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 78648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 78748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 788e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 789e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 79048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 79148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 792ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 79357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || 79457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 795ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 796ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 797e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 798e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 799ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 800505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 801a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isMemImm8s4Offset() const { 80257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 803a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 804a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate offset a multiple of 4 in range [-1020, 1020]. 805e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 806e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 807a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 808a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 809b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach bool isMemImm0_1020s4Offset() const { 81057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 811b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return false; 812b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // Immediate offset a multiple of 4 in range [0, 1020]. 813e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 814e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 815b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 816b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 8177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 81857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 819f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 8207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 821e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 822e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8234d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson return (Val == INT32_MIN) || (Val > -256 && Val < 256); 824f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 825f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach bool isMemPosImm8Offset() const { 82657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 827f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return false; 828f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach // Immediate offset in range [0, 255]. 829e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 830e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 831f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return Val >= 0 && Val < 256; 832f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 833a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemNegImm8Offset() const { 83457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 835a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 836a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [-255, -1]. 837e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 838e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 839a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return Val > -256 && Val < 0; 840a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 841a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemUImm12Offset() const { 842a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 843a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 844a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // and we reject it. 84521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 846a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return true; 847a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 84857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 849a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 850a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [0, 4095]. 851e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 852e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 853a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return (Val >= 0 && Val < 4096); 854a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 8557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 85609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 85709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 85809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 85921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 86009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 86109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 86257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 863ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 8647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 865e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetImm) return true; 866e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm->getValue(); 8670da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 8687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 8697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 87021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 8717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 8727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 873ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 8747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 87563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 876ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 8777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 87821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMSRMask() const { return Kind == k_MSRMask; } 87921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isProcIFlags() const { return Kind == k_ProcIFlags; } 8803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 881460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex8() const { 882460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 883460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 8; 884460a90540b045c102012da2492999557e6840526Jim Grosbach } 885460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex16() const { 886460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 887460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 4; 888460a90540b045c102012da2492999557e6840526Jim Grosbach } 889460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex32() const { 890460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 891460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 2; 892460a90540b045c102012da2492999557e6840526Jim Grosbach } 893460a90540b045c102012da2492999557e6840526Jim Grosbach 894460a90540b045c102012da2492999557e6840526Jim Grosbach 895460a90540b045c102012da2492999557e6840526Jim Grosbach 8963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 89714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 89814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 89914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 90014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 9013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 9023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 9033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 9043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 9053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 907345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 9088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 90904f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 91004f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 9118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 9128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 913fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 914fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 915fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 916fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 917fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 91889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 91989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 92089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 92189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 92289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 92389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 92489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 92589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 92689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 92789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 928fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 929fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 930fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 931fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 932fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 933d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 934d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 935d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 936d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 937d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 938a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 939a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 940a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 941a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 942a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 943af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 944e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 945af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 946af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 947af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 948e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 949af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 950e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 951e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 952af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 953152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 954af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 955af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 95692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 957af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 95892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 95992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 960580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 9610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 962580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 963580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 9640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 9650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 96687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 9677729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 9685fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 9695fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 9707729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 9717729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 97287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 97387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 9740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 9750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 9760f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 9770f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9780f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 9790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 9800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 9810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 9837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 9857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 9867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 9877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 988293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 989293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 990293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 991293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 992293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 993293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 994293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 995293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 996293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 997293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 998293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 9993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 10006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 10026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 10036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 10049d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 10059d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10069d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 10079d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 10089d39036f62674606565217a10db28171b9594bc7Jim Grosbach 1009a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1010a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1011a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 1012a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 1013a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1014a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1015a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1016a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 101772f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 101872f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 101972f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 102072f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 102172f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 102272f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 102372f39f8436848885176943b0ba985a7171145423Jim Grosbach } 102472f39f8436848885176943b0ba985a7171145423Jim Grosbach 102572f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 102672f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 102772f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 102872f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 102972f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 103072f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 103172f39f8436848885176943b0ba985a7171145423Jim Grosbach } 103272f39f8436848885176943b0ba985a7171145423Jim Grosbach 10336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 10346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10356b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 10366b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 10376b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 103883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 103983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 104083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 104183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 104283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 104383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 10447c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10457c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 10467c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 10477c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 10487c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 104983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 105083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 105183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 105283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 1053f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1054f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1055f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1056f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1057f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1058f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1059f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1060f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 10614a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 10624a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10634a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 10644a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 10654a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10664a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 10674a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 10684a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 1069fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 1070fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1071fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 1072fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 1073fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 1074ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 1075ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1076ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 1077ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 1078ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 1079ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 1080ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1081ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 108270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 108370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 108470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 108570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 108670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 108770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 108870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 108970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 109070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1091ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1092ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1093f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 1094f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1095f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 1096f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1097f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1098f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1099f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1100f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1101f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1102f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1103f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1104f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1105f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1106f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 11076bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 11086bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 11096bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 11106bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 11116bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 11126b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 11133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 11143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 11153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 111616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1117c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 1118c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1119c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 1120c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1121c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1122706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1123706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1124706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1125706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1126706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 11277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 11287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1129e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1130505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1131505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 113257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 113357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 113457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 113557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 113657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 113757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 11387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 11397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1140e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1141e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 11427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 11437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 11447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 11457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 11467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 11477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 11487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 11497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 1150e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1151e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1152ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1153e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1154e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 11557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1156ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1157ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1158039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1159039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1160039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1161039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1162039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1163039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1164039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1165039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1166039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1167039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1168039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1169039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1170039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1171039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 11722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 11732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1174e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1175e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach if (!Memory.OffsetRegNum) { 11762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 11772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 11782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 11792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 11802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 11812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 11822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 11832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 1184e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 11852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 1186e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1187e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 11882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 11892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 11902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 11912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 11922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 119321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) { 11942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 11952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 11962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 11972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1198251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 11992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 12002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 12012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 12022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 12032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 12042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 12062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 12072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1208251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 12092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 12102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 12122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 12137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 12147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 12157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1216e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 12177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 12197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 12207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 12217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 1222e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 12237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 12257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1226a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1227a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1228e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1229e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1230a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1231a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1232a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1233b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1234b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1235b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1236e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1237e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1238b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1239b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1240b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 12417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 12427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1243e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1244e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 12457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1246ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1247ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1248f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1249f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1250f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1251f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1252a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1253f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1254a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1255a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1256a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1257a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1258a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 125921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 1260a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1261a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1262a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1263a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1264a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1265a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1266e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1267e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1268a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1269a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1270a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 12717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 12727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 127309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 127421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 127509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 127609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 127709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 127809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 127909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 128009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1281e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1282e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 12837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 128592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 12867f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 12877f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1288e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1289e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 12907f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 12917f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 12927f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 12937f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1294e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1295e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 12967f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 12977f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 12987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 12997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 1300e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1301e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Memory.ShiftImm, Memory.ShiftType); 1302e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1303e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 13047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 13057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1306d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1307ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1308ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1309e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1310e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1311e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 1312ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1313ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 13147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 13157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1316e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1317e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 131814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 13193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 132060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 132160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1322e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1323e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 132460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 132548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 132648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 132738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 132838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1329e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 1330e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 133138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 133238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 133338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 133448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 133548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1336e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 1337e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 133848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 133960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 134060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1341ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1342ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1343e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1344e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1345ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1346ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1347ecd858968384be029574d845eb098d357049e02eJim Grosbach 13487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 13497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 13517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 13527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 13537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 135463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 13557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 13567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1357f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1358ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 13597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 13607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 13617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1362f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1363f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1364f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1365f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1366f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1367f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1368f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1369f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1370f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1371f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1372f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1373f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1374ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1375ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1376584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1377584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1378584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1379584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1380584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1381a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1382a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1383a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1384a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1385a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1386460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1387460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1388460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1389460a90540b045c102012da2492999557e6840526Jim Grosbach } 1390460a90540b045c102012da2492999557e6840526Jim Grosbach 1391460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1392460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1393460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1394460a90540b045c102012da2492999557e6840526Jim Grosbach } 1395460a90540b045c102012da2492999557e6840526Jim Grosbach 1396460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1397460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1398460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1399460a90540b045c102012da2492999557e6840526Jim Grosbach } 1400460a90540b045c102012da2492999557e6840526Jim Grosbach 1401b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1402b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 140389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 140421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ITCondMask); 140589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 140689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 140789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 140889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 140989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 141089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 14113a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 141221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CondCode); 1413345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1414345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1415345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 14163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1417345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1418345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1419fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 142021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocNum); 1421fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1422fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1423fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1424fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1425fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1426fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1427fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 142821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocReg); 1429fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1430fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1431fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1432fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1433fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1434fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1435d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 143621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CCOut); 1437d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1438d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1439d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1440d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1441d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1442d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 14433a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 144421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Token); 1445762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1446762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1447762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1448762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 14493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1450a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1451a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 145250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 145321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Register); 1454762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1455762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1456762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 14573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1458a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1459a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1460e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1461e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1462e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1463e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1464e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 146521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1466af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1467af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1468af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1469af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1470e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1471e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1472e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1473e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1474e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 147592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 147692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 147792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 147892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 147921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1480af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1481af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1482af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 148392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 148492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 148592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 148692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 148792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1488580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 14890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 149021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1491580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1492580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 14930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 14940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 14950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 14960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 14970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 149921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_RotateImmediate); 15007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 15017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 15027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 15037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 15047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 15057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1506293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1507293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 150821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 1509293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1510293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1511293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1512293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1513293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1514293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1515293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 15167729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 15175fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1518cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 151921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach KindTy Kind = k_RegisterList; 15200f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1521d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 152221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_DPRRegisterList; 1523d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1524275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 152521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_SPRRegisterList; 15260f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 15270f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 15285fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 15297729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 153024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1531cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1532cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1533cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 15348d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 15358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 15368d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 1537460a90540b045c102012da2492999557e6840526Jim Grosbach static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 1538460a90540b045c102012da2492999557e6840526Jim Grosbach MCContext &Ctx) { 1539460a90540b045c102012da2492999557e6840526Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorIndex); 1540460a90540b045c102012da2492999557e6840526Jim Grosbach Op->VectorIndex.Val = Idx; 1541460a90540b045c102012da2492999557e6840526Jim Grosbach Op->StartLoc = S; 1542460a90540b045c102012da2492999557e6840526Jim Grosbach Op->EndLoc = E; 1543460a90540b045c102012da2492999557e6840526Jim Grosbach return Op; 1544460a90540b045c102012da2492999557e6840526Jim Grosbach } 1545460a90540b045c102012da2492999557e6840526Jim Grosbach 15463a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 154721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Immediate); 1548762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1549762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1550762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 15513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1552cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1553cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 15549d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 155521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_FPImmediate); 15569d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 15579d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 15589d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 15599d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 15609d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 15619d39036f62674606565217a10db28171b9594bc7Jim Grosbach 15627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 15637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 15647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 15657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 15660d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 156757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Alignment, 15687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 15693a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 157021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Memory); 1571e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.BaseRegNum = BaseRegNum; 1572e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetImm = OffsetImm; 1573e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.OffsetRegNum = OffsetRegNum; 1574e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftType = ShiftType; 1575e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.ShiftImm = ShiftImm; 157657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Op->Memory.Alignment = Alignment; 1577e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach Op->Memory.isNegative = isNegative; 15787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 15797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 15807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 15817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 158216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1583f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1584f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1585f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 15867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 158721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 15887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1589f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1590f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1591f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1592762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1593762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 15943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1595a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1596706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1597706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 159821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 1599706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1600706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1601706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1602706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1603706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1604a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1605a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 160621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ProcIFlags); 1607a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1608a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1609a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1610a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1611a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1612584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1613584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 161421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MSRMask); 1615584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1616584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1617584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1618584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1619584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1620a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1621a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1624b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1625fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 162621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 16279d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 16289d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 16299d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 163021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 16316a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1632fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 163321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 1634d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1635d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 163621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: { 163789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)", 163889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)", 163989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(tee)", "(eee)" }; 164089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 164189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 164289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 164389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 164421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 1645fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1646fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 164721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 1648fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1649fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 165021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 1651584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1652584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 165321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 1654fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1655fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 165621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 1657706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1658706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 165921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 16606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 1661e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach << " base:" << Memory.BaseRegNum; 16626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1663fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 166421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 1665f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1666f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1667f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1668f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1669f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1670f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 16717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 167221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: { 1673a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1674a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1675a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1676a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1677a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1678a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1679a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1680a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 168121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 168250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1683fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 168421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 1685580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1686580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1687e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 168821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 168992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1690af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1691af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1692af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1693af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1694e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 16950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 169621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 169792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1698af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1699af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1700af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 170192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 170292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 170321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 17047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 17057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 170621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 1707293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1708293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1709293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 171021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 171121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 171221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: { 17138d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 17148d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 17155fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 17165fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 17177729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 17187729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 17197729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 17208d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 17218d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 17228d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 17238d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 17248d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 172521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 1726fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1727fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1728460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 1729460a90540b045c102012da2492999557e6840526Jim Grosbach OS << "<vectorindex " << getVectorIndex() << ">"; 1730460a90540b045c102012da2492999557e6840526Jim Grosbach break; 1731fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1732fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 17333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 17343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 17353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 17363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 17373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 17383483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 17393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 17403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 174169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 174269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 17431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1744bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1745bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1746bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1747bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 17489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1749e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1750e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 17513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 17521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 175318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 17547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1755d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1756a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1757a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 17580c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 17590c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 17600c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 17610c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 17620c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 17630c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 17640c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 17650c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 17660c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 17670c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 17680c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 17690c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 177069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1771b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1772460a90540b045c102012da2492999557e6840526Jim Grosbach 1773460a90540b045c102012da2492999557e6840526Jim Grosbach#if 0 1774460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 1775460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 1776460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 1777460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 1778460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 1779460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 1780460a90540b045c102012da2492999557e6840526Jim Grosbach 1781460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 1782460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc ExprLoc = Parser.getTok().getLoc(); 1783460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 1784460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1785460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 1786460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 1787460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 1788460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1789460a90540b045c102012da2492999557e6840526Jim Grosbach } 1790460a90540b045c102012da2492999557e6840526Jim Grosbach 1791460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 1792460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 1793460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 1794460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1795460a90540b045c102012da2492999557e6840526Jim Grosbach } 1796460a90540b045c102012da2492999557e6840526Jim Grosbach 1797460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 1798460a90540b045c102012da2492999557e6840526Jim Grosbach 1799460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 1800460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 1801460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 1802460a90540b045c102012da2492999557e6840526Jim Grosbach } 1803460a90540b045c102012da2492999557e6840526Jim Grosbach#endif 1804460a90540b045c102012da2492999557e6840526Jim Grosbach 1805e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1806e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1807d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 180819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 180919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 181019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 181119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 181219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 18130d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 18140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 18150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 18160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 18170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 18180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 18190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 18200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 18210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 18220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 18230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 18240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 18250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 18260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 18270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 18280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 18290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 183019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 18310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1832e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1833e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1834e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1835e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1836e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1837eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1838e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1839e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1840e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1841e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1842e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1843e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1844e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1845e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1846e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1847e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1848e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1849e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1850e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1851e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1852e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1853e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 185419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 185519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 185619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 185719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1858e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1859e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 186019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 186119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 186219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 186319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1864e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1865e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1866e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1867e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1868e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1869e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1870e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 187119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 187219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1873e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1874e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 18751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1876e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 187719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 187819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 187919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 188019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 188119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 188219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1883e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 188419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 188519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1886e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1887e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 188892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 188992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1890af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 18910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 189292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 189392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 189492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 18950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 189619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 18970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 18980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 18990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 190050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 190150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 190250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1903e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1904e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1905e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 190650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 19071355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1908e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 19091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1910e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 191150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1912d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 191350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1914a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1915e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1916e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 191750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 191850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1919e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 1920460a90540b045c102012da2492999557e6840526Jim Grosbach return false; 1921460a90540b045c102012da2492999557e6840526Jim Grosbach } 1922460a90540b045c102012da2492999557e6840526Jim Grosbach 1923460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 1924460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 1925460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 1926460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 1927460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 1928460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 1929460a90540b045c102012da2492999557e6840526Jim Grosbach 1930460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 1931460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc ExprLoc = Parser.getTok().getLoc(); 1932460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 1933460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1934460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 1935460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 1936460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 1937460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1938460a90540b045c102012da2492999557e6840526Jim Grosbach } 1939460a90540b045c102012da2492999557e6840526Jim Grosbach 1940460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 1941460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 1942460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 1943460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1944460a90540b045c102012da2492999557e6840526Jim Grosbach } 1945460a90540b045c102012da2492999557e6840526Jim Grosbach 1946460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 1947460a90540b045c102012da2492999557e6840526Jim Grosbach 1948460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 1949460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 1950460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 195199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 195299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 195350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1954a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1955a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1956fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1957fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1958fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1959fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1960e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1961e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1962e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1963e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1964e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1965fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1966e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1967e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1968e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1969e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1970e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1971e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1972e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1973e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1974e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1975e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1976e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1977e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1978e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1979e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1980e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1981e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1982fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1983e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1984e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1985e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1986e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1987e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1988e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1989e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1990e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1991e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1992e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1993e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1994e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1995e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1996e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1997e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1998e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 199989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 200089df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 200189df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 200289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 200389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 200489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 200589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 200689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 200789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 200889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 200989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 201089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 201189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 201289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 201389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 201489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 201589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 201689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 201789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 201889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 201989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 202089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 202189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 202289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 202389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 202489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 202589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 202689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 202789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 202889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 202989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 203089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 203189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 203289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 203389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 203443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2035fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2036fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2037f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 203843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2039e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 2040e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 2041e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2042e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2043fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2044e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 2045f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2046e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2047e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 2048fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2049f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2050fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 2051fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 205243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2053fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2054fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2055f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 205643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2057fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2058fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2059fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2060fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2061fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2062fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 2063f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2064fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2065fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2066fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2067f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2068e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2069e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2070d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 2071d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 2072d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 2073d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 2074d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 2075d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 2076d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 2077d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2078d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 2079d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 2080d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 2081d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2082d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2083d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2084d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2085d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2086d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2087d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2088d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2089d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2090d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 2091d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2092d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 209350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 20941355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 209518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 2096a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 2097e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 2098d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 2099d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 210016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2101d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 2102d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 2103d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 2104d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 2105d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 2106d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2107d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach MCRegisterClass *RC; 2108d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2109d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2110d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2111d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2112d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2113d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2114d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 2115d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2116e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 2117d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 2118d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // space for that many. 2119d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2120d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Store the first register. 2121d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2122d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2123d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 2124d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 2125d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 2126d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2127d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2128d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2129d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2130d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2131d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 2132d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2133d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2134d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2135d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2136d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2137d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2138d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2139d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2140d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2141d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2142d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2143d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2144d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2145d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2146d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2147d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2148d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2149d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2150d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2151d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2152d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2153d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2154d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2155d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2156d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 21572d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2158d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2159d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2160d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2161d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2162d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg)) 2163d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2164d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2165d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2166d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2167d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2168d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2169d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2170d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2171d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2172d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2173d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2174d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2175d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2176d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2177e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 217850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 217950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2180d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2181d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 218243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2183f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 218443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2185706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2186706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2187706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2188706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 2189706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2190706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 2192706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 2193032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 2194706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 2195032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 2196706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 2197706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 2198032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 2199706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 2200032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 2201706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 2202706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 2203706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 2204706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2205706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 2206f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2207706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2208706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2209706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2210f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2211706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 2212706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 221343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2214a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 221543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2216a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2217a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2218a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2219a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 2220a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 22212dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // An iflags string of "none" is interpreted to mean that none of the AIF 22222dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // bits are set. Not a terribly useful instruction, but a valid encoding. 2223a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 22242dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (IFlagsStr != "none") { 22252dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 22262dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 22272dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("a", ARM_PROC::A) 22282dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("i", ARM_PROC::I) 22292dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("f", ARM_PROC::F) 22302dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Default(~0U); 22312dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 22322dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // If some specific iflag is already set, it means that some letter is 22332dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // present more than once, this is not acceptable. 22342dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (Flag == ~0U || (IFlags & Flag)) 22352dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson return MatchOperand_NoMatch; 22362dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 22372dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson IFlags |= Flag; 22382dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson } 2239a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2240a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2241a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2242a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2243a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 2244584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 2245584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 224643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2247584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 224843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2249584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2250584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2251584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2252584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 2253584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2254acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 2255acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 2256acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2257acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 2258acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 2259acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 2260acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 2261acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 2262acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 2263acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 2264acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 2265acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 2266acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 2267acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 2268acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 2269acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 2270acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 2271acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 2272acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2273acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 2274acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2275acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2276acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 2277acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 2278acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2279acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2280acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 2281acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2282acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 2283acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 2284acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2285584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 2286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 2287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 2288b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 2289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 2290584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 2291584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2292584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 2293584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 2294584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 2296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 2298584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 2299b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 2300584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 2301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 2302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 23044b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 2305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 2306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 2308bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 23094b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 2310584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 231156926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 231256926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 2313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 2314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 2315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 2316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 2317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 2318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 2319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2321584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 2322584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 2323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 2324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 2326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 2328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2329584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2330584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 2331584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 2332584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 2333584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2334584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 2336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 2337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2340584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 2341a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 2342a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2343f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2344f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 2345f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 2346f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2347f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2348f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2349f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2350f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2351f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 2352f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 2353f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 2354f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 2355f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2356f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2357f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2358f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 2359f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2360f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 2361f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2362f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 2366f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2367f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 2368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 2369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 2371f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2372f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2373f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2374f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 2375f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 2376f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2377f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2378f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 2379f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 2380f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 2381f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2382f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2383f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2384f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 2385f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2386f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 2387f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 2388f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2389c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2390c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2391c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2392c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 2393c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2394c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2395c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2396c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2397c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 2398c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 2399c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 2400c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 2401c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 2402c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2403c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 2404c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2405c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2406c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2407c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 2408c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 2409c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 2410c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 2411c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 2412c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2413580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 2414580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 2415580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 2416580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 2417580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 2418580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2419580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2420580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 2421580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 2422580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2423580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2424580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2425580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2426580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 2427580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 2428580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 2429580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 2430580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 2431580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 2432580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 2433580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2434580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2435580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 2437580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2438580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 2439580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2440580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2441580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2442580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2443580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 2444580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2445580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 2446580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2447580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2448580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 2449580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2450580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2451580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 2453580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 2454580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2455580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2456580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2457580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 2458580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 2459580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2460580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 2461580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 2462580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2463580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 24640afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 24650afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 24660afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 24670afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 24680afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 2469580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 2470580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 2471580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2472580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 2473580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 2474580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2475580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2476580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2477580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2478580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 2479580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 2480580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2481580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 2482580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 2483580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 24847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 24857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 24867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 24877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 24887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 24897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 24907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 2491326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2492326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 24937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 2494326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 2495326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 24967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 24977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 24987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 24997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 25007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 25017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 25027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 25037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 25047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 25057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 25067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 25077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 25087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 25097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 25107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 25117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 25127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 25137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 25147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 25157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 25167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 25177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 25187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 25197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 25207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 25217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 25227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 25237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 25247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 25257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 25267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 25277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 25287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 25297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 25307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 25317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2532293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2533293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2534293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2535293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2536293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2537293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2538293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2539293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2540293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2541293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2542293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2543293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2544293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2545293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2546293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2547293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2548293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2549293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2550293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2551293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2552293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2553293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2554293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2555293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2556293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2557293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2558293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2559293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2560293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2561293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2562293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2563293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2564293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2565293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2566293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2567293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2568293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2569293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2570293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2571293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2572293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2573293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2574293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2575293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2576293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2577293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2578293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2579293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2580293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2581293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2582293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2583293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2584293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2585293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2586293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2587293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2588293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2589293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2590293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2591293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2592293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2593293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2594293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2595293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2596293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2597293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 25987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 25997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 26007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2601f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2602f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2603f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 26047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 26057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 26067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 26077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 26087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 26097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 26107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 261116578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 26127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 26137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 26147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 26157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 26167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 26177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 261816578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 26197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 26207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 26217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 26227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 26237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 26247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 26257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 26267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 26277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 26287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 26297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 26307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2631f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2632f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 26330d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 26340d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 26350d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 26360d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 26370d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2638f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2639f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2640f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 26417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 26427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 26437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 26447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2645251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2646251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2647251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2648251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2649251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2650251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2651251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2652251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2653251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2654251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2655251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2656251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2657251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2658251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2659251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2660251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2661251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2662251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2663251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2664251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2665251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2666251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2667251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2668251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2669251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2670251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2671251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2672251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2673251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2674251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2675251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2676251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2677251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2678251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2679251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2680251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2681251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2682251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2683251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2684251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2685251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2686251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2687251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2688251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2689251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2690251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2691251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2692251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2693251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2694251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2695251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2696251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2697251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2698251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2699251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2700251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2701251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2702251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2703251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2704251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2705251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2706251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2707251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2708251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2709251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2710251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 2711251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2712251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2713251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 2714251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2715a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 2716a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2717a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2718a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 2719a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 2720a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2721a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 2722a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2723a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2724a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 2725a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 2726a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 2727a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 2728a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 2729a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2730a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 2731a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 2732a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 2733a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 2734a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2735a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2736a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 2737a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 2738a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2739a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 2740a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 2741a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 2742a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2743a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2744a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 2745a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 2746a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 2747a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2748a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 2749a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 2750a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 2751eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 2752eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2753eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2754eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 2755eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 2756eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2757eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2758eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2759eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 2760eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2761eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2762eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 2763eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2764eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 2765eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 2766eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2767ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 2768ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2769ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2770ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 2771ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 2772ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2773ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 2774ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2775ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2776ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 2777ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2778ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 2779ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 2780ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 27811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2782ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2783ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2784ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 27851355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2786ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2787ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2788ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2789ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2790ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2791ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 27927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2793ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2794ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2795ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2796ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 27979ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 27989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 27999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 28009ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 28019ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 28029ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28039ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 28049ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 28059ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 28069ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 28079ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 28089ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 28099ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 28109ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 28119ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 28129ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 28139ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 2814548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2815548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2816548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2817548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 2818548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2819548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2820548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 2821548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2822548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2823548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2824548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2825548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 2826548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 2827548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 28281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2829ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2830ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2831ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 28321355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2833ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2834ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2835ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2836548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2837548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2838548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 28397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 28407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 28417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 28427b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 28437b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 28447b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 28457b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 28467b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 28477b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28487b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 28497b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 28507b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 28517b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 28527b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 28537b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 28547b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 28557b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 28567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 28577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 28587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 28597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 28607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 28617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2863ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 28647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 28657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 28667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 28677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 28687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 28697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 28707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2871ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2872ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2873ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2874ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 28757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2876ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2877ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2878ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 28797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 28807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2882aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2883ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2884ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 28857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 28867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 28877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 28887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 28897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 28907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 28917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 28927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 2893aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 28947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 28957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 28967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 28977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 28987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 28997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 29007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 29017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 29027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 29037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 29047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 29057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 29067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 29077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 29087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2909ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2910ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2911ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2912ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 29137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2914ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2915ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2916ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 29177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 29187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2919ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2920ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 29217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2922ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 29237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 29247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 29257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 29267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 29277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2928ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2929ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2930ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2931ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 29322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 29332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 29342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 29352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 29362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 29372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 29382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 29392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 29402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 29412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 29422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 29432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 29442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 29452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 29462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 29472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 29482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 29492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 295014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 295114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 295214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 295314605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 295414605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 295514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 295614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 295714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 295814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 295914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 296014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 296114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 296214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 296314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 296414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 296514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 296614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 296714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 2968623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2969623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2970623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2971623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 2972623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2973623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2974623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2975623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 2976623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2977623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2978623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2979623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 2980623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 2981623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 298288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 298388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 298488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 298588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 298688ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 298788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 298888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 298988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 299088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 29917a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 29927a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 29937a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 29947a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 299588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 29967a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 299788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 299888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 299988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 300088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 300188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 30027a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // If we have a three-operand form, use that, else the second source operand 30037a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // is just the destination operand again. 30047a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach if (Operands.size() == 6) 30057a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 30067a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach else 30077a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach Inst.addOperand(Inst.getOperand(0)); 300888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 300988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 301088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 301188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 3012623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 3013e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 30149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 301550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 30167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3017762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 301818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3019a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 3020762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3021b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 3022a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 302318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 30241355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 30257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 30267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 3027a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30280571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 30290571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 30300571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 30317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 30320571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 30337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 3034762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 3035b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 3036a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 303857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 0, 0, false, S, E)); 303903f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 3040fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3041fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 3042fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3043fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3044fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 3045fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 3046fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 30477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 30487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 304950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 30507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 30517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 305250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 305357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a ':', it's an alignment specifier. 305457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Colon)) { 305557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the ':'. 305657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 305757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 305857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCExpr *Expr; 305957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (getParser().ParseExpression(Expr)) 306057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return true; 306157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 306257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // The expression has to be a constant. Memory references with relocations 306357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // don't come through here, as they use the <label> forms of the relevant 306457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // instructions. 306557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 306657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (!CE) 306757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error (E, "constant expression expected"); 306857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 306957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach unsigned Align = 0; 307057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach switch (CE->getValue()) { 307157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach default: 307257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "alignment specifier must be 64, 128, or 256 bits"); 307357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 64: Align = 8; break; 307457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 128: Align = 16; break; 307557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach case 256: Align = 32; break; 307657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 307757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 307857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Now we should have the closing ']' 307957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach E = Parser.getTok().getLoc(); 308057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 308157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return Error(E, "']' expected"); 308257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat right bracket token. 308357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 308457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // Don't worry about range checking the value here. That's handled by 308557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // the is*() predicates. 308657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 308757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, Align, 308857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 308957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 309057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 309157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // operand. 309257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 309357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 309457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach Parser.Lex(); // Eat the '!'. 309557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 309657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 309757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach return false; 309857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach } 309957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach 310057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach // If we have a '#', it's an immediate offset, else assume it's a register 31017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 31027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 31037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 31047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 310550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 31060da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 31077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 31087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 31097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 311005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 31117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 31127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 31137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 31147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 31157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 31167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 31177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 31180da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 31190da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 31200da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 31210da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 31220da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 31237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 31247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 31257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 31267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 31277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 312805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 31297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 31307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 31317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 313257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ARM_AM::no_shift, 0, 0, 313357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach false, S, E)); 3134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 31357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 31367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 31377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 31387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 31397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 3140762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 31417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 31427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 31439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 3144d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 31457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 31467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 31477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 31487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 31497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 31507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 31517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 31527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 31537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 31549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 31557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 31567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 31577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 31587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 31597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 31607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 31617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 31620d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 31637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 31647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 31650d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 31667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 31679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 316816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 31697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 31707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 31717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 31727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 31737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 31747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 31757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 317657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach ShiftType, ShiftImm, 0, isNegative, 31777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 31787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3179f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3180f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 3181f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3182f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3183f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 3184f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 31859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 31869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 31879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 31889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 31897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 3190a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 3191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 31927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 31937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 31947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 31957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 319618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 319938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 3200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 32010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 3202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 32030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 3204a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 32050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 3206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 32070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 3208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 32090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 3210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 32117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 3212b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 3213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 32147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 32157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 32167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 32177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 32187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 32197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 32207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 32217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 32227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 32239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 32247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 32257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 32267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 32277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 32287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 32297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 32307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 32317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 32327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 32337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 32347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 32357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 32367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 32377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 32387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 32397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 3240a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 3242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 32449d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 32459d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 32469d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 32479d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 32489d39036f62674606565217a10db28171b9594bc7Jim Grosbach 32499d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) 32509d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 32519d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 32529d39036f62674606565217a10db28171b9594bc7Jim Grosbach 32539d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 32549d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 32559d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 32569d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 32579d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 32589d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32599d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 32609d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 32619d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 32629d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 32639d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 32649d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 32659d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 32669d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 32679d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 32689d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 32699d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 32709d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32719d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 32729d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 32739d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32749d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 32759d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 32769d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 32779d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 32789d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 32799d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 32809d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32819d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 32829d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 32839d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32849d39036f62674606565217a10db28171b9594bc7Jim Grosbach 32859d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 32869d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 32879d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 32889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 32899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 32901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3291fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 3292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 3293fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3294fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 3295fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 3296f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 3297f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 3298fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 3299f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 3300f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 3301f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 3302f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 3303f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 3304fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 3306146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 3307146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 330850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 330919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 33105cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 33111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 331250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 33130d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 331419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 33150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 331619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 331719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 33185cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 33195cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 33205cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 33215cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 33225cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 33235cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 3324e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 3325e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 3326e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 332719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 332867b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 332967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 3330515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 3331515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 3332515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 3333762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3334515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 333550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 3336762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 333750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 333850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 333950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 3340a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 33411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 3342d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 33431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 334463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 3345079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 3346079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 3347762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3348b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 334963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 3350515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 3351515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 335250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 335363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 335463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (!CE) { 335563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson Error(S, "constant expression expected"); 335663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return MatchOperand_ParseFail; 335763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 335863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson int32_t Val = CE->getValue(); 335963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (isNegative && Val == 0) 336063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 3361762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 336250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 336350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 336463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 33659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 33669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 33677597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 33687597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 33697597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 33701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 33719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 33729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33737597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 33747597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 33759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 33769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33777597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 33787597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 33799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 33807597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 33819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 33829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 3383a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3384a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3385a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 33861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 33877597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 33881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 33897597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 33909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 33928a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 33939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 33949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 33969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 33979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 33989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 33999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 34009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 34019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 34027597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 34039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 34047597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 34059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 34069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 34079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 34089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 34099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 34109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 34119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 34129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 34139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 34149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 34159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 34169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 34179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 34189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 3419352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 3420352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 3421352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 3422badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 342389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 34241355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 34255f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 34265f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 342789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 342889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 3429352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 3430352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 3431a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 3432352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3433badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 3434352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 3435352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 34365f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 34375f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 34385f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 34395f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 34405f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 34415f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 34425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 34435f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 3444352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3445badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 34463f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 34473f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 3448ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 344971725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 345004d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 34512f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 34523f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 34533f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 34543f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 34553f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 34563f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 34573f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 34583f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 34593f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 34603f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 34613f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 34623f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 34633f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 34643f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 34653f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 34663f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 34673f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 34683f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 34693f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 34703f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 34713f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 34723f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 34733f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 34743f00e317064560ad11168d22030416d853829f6eJim Grosbach } 347552925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 3476345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3477352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 3478352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 3479352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 348000f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 34815f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 34825f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 34835f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 3484e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 3485e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 3486352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 3487352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 3488352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 3489352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3490a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 3491a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 3492a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 3493a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 3494a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 3495a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 3496a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 3497a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 3498a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 3499a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 3500a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 3501a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 3502a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3503a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3504a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 350589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 350689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 350789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 350889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 350989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 351089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3511352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3512352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 35133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 35143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 35153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 35163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 35173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 3518fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 35191355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 3520fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 3521eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 3522eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 35233443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 3524eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 3525d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 3526eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 3527d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 35283443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 3529d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 3530d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 3531eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 3532fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 3533eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 35343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 3535eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 3536eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 3537eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 3538eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 3539ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 3540ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 35410780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 35424af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw") && 35434af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 35444af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 35454af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 35461ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 35473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 3548fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 35493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 3550fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 3551fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 3552fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 355363b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 3554fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 3555fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 3556badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 3557badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3558d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 3559d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 356020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 356120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 3562d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3563d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 3564d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 3565d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 3566d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 3567d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 3568d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 3569d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 3570d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 35718adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 3572d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 3573d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 3574d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3575d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 35763912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 35773912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 35783912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 35793912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 35803912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 35813912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 35823912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 35833912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 358472f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 358520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 358620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 358720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 3588f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 3589f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 3590f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 359172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 359272f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 359372f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 359420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 359520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 359620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 359772f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 3598f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 3599f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 360020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 360120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 360220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 3603f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 3604f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 360520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 360620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 360720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 360820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 360920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 361020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 361120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 361220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 361320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 361420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 361520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 361620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 361720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 361820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 361920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 362064944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 362120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 362220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 362320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 362420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 362520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 362620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 362720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 362820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 362920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 363064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 363164944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 363264944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 363364944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 363464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 363564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 363664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 363764944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 363864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 363964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 364064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 364164944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 364264944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 364364944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 364464944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 364564944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 364664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 364764944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 364864944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 364964944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 365064944f48a1164c02c15ca423a53919682a89074cJim Grosbach 365164944f48a1164c02c15ca423a53919682a89074cJim Grosbach 365220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 3653f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 3654f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 3655f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 3656f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 3657f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 3658f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 3659f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 366072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 366172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 366272f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 366372f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 36643912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 3665d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 3666d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 3667d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3668badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 3669badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 3670badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3671badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 3672badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 3673ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 3674badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3675352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 3676352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 3677a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 3678352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 367989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 36801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 368189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 3682badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 36830c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 36840c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 36850c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 36860c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 36870c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 36880c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 3689ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 3690ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 369189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 369289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 369389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 369489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 369589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 369689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 3697f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 3698f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 3699f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 3700f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 3701f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 370289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 370389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 370489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 370589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 370689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 3707f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 370889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 370989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 371089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 371189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 371289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 3713f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 371489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 371589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3716ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 3717ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 37189717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 37193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 37203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 37213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 37223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 37233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 37243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 37253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 37263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 37271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 37283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 372933c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 373033c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 373133c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 373233c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 3733ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 373433c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 373533c16a27370939de39679245c3dff72383c210bdJim Grosbach } 3736c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 3737c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 3738c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 3739c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 3740c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 3741c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 3742c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 374333c16a27370939de39679245c3dff72383c210bdJim Grosbach 37443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 3745f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 3746f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 37473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 3748f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 3749f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 37503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 37513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 37523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 3753f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 3754f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 37553771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 3756f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 3757badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 3758345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3759a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 3760a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 3761a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 3762a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 3763a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 3764a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3765a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3766345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 37675747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 37685747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 37695747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 3770a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 3771a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 37724d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // For now, we're only parsing Thumb1 (for the most part), so 37734d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // just ignore ".n" qualifiers. We'll use them to restrict 37744d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // matching when we do Thumb2. 377581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 377681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 377781d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 377881d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 37795747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 37805747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 37815747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 37825747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 3783a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 37841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3785cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3786cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3787cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3788a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3789a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 3790b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 3791a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3792a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 37931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3794cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3795cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3796cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3797a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3798a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 379916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3800cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 3801186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach SMLoc Loc = getLexer().getLoc(); 3802cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3803186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach return Error(Loc, "unexpected token in argument list"); 3804cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3805146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 380634e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 3807ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3808d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 3809d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 3810d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 381120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 381220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 381320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 381420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 381520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 3816ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3817ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 3818ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 3819ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 3820ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3821cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 3822cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 3823cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 382421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // a k_CondCode operand in the list. If we're trying to match the label 382521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // version, remove the k_CondCode operand here. 3826cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 3827cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 3828cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3829cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 3830cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 3831cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 3832857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 3833857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 3834857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 3835857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 3836857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 3837857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 3838857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3839857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3840857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3841857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 3842857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 3843857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 384468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 384568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 384668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 384768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 384868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 384968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 385068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 385168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 385268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 385368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 385468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3855857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 3856857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3857857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3858934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 3859934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 3860934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 3861934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3862934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3863934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3864934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 3865934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 3866934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3867934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 3868934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3869934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3870934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 38719898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 3872ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3873ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3874189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 3875aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3876aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 3877aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 3878aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 3879aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 3880aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 3881aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 3882aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 3883aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 3884aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 3885aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 3886aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 3887aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 3888aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 3889aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 3890aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 3891aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 3892aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 389376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 389476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 389576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 389676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 389776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 389876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 389976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 390076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 390176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 390276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 390376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 3904f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 3905f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 3906f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 3907f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 3908f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[]; 3909f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 3910f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 3911f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 3912f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 3913f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 3914189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 3915189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 3916189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 3917189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3918f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 3919f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 3920f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 3921b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 3922b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 3923b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 3924b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 3925f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 3926f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 3927f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 3928f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 3929a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 3930f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 3931f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 3932f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 3933f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 3934f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 3935f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 3936f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 3937f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 3938f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 3939f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 3940f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 3941f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 3942f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 3943f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 3944f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 3945f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 3946f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 3947c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 3948f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 3949f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 395051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 395151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 3952f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 3953f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 3954189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 39552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 39562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 39572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 3958189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 3959189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3960189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 3961189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3962189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 3963189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 3964189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 3965189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3966189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 396714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 396814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 396914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 397014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 397114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 397214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 397314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 397414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 397514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 397653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 397753642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 3978189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 3979189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3980189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3981189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 3982189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 398314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 3984189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 3985189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3986189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3987fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 3988fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 3989fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 3990fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 3991fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 3992fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 3993fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 3994fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 399500c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 3996fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 399793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 399876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 399976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 400076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 400176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 400276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 400393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 400493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 400593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 40067260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 40077260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 40087260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 4009aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 401076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 4011aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 4012aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 401393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 401476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 401593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 401693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 401776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 401876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 4019aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 40207260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 40217260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 40227260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 402393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 402493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 402593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 402676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 402776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 402876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 402976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 403076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 403176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 403276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 40336dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 4034aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 4035aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 4036aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4037aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 40386dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 40396dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 40406dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 4041aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 4042aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 4043aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 4044aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 40456dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 40466dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 40471e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 40481e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 40498213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 40501e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 40511e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 40521e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 40531e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 4054189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 4055189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4056189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 4057189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 4058189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4059f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 4060f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 4061f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4062f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 4063f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 4064f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 4065f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 4066f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 4067f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 4068f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 4069f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 4070f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4071f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4072f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 4073f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 4074f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 4075f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4076f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4077f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 4078f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4079f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 4080f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 4081f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 4082f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 4083f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 4084f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 4085f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 4086f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 4087f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4088f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4089f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 4090f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 4091f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4092f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4093f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 4094f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 4095f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 409689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 40970f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 40980f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 40990f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 41000f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 41010f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 410289e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 410389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 4104f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 4105f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 4106f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 4107f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 4108f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 4109f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 4110f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 4111f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 411251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 411351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 411451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 411551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 411651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 411751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 411851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 411951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 412051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 412151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 4122c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 4123a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 4124a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) 4125c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 4126c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 4127395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 4128395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 4129395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) 4130395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 41313ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 413276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 413376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 413476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 413576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 413676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 413776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 413876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 413976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 414076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 414176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 414276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 414376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 414476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 414576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 414676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 414776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 414876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 414976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 415076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 415176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 415276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 415376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 415476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 415576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 41568213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 41578213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 41588213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 41598213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 41608213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 41618213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 41628213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 41638213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 41648213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 41658213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 41668213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 41678213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 41688213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 41691ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 41701ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 41711ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 41721ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 41731ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 4174c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 4175c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 4176c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 41771ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 41781ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 41791ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 41801ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 41811ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 41821ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 41831ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 41841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 41851ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 41861ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 41871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 41881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 41891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 41901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 41911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 41921ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 41931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 41941ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 41951ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 41961ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 41971ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 41981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 41991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 42001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 42011ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 42021ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 42031ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 42041ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 42051ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 42061ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 42071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 42081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 42091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 42101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 4211326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 421250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 421350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 421450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 4215326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 4216326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 4217326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4218326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4219326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 4220326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4221326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 422250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 422350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 422450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 422550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 422650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 422750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 422850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 422950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 4230326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 4231326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 4232326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 4233326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 4234326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 4235326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4236326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 4237326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 4238326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 4239326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 4240326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 424189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 424289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 424389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 424489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 424589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 424689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 424789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 424889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 424989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 4250f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 4251f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 425289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 425389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 425489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 425589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 425689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 425789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 425889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 4259f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4260f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 4261f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 4262f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 4263f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 4264f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 4265f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 4266f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 426789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 426889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4269f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4270f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 4271f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 427247a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 427347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 427447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 4275194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 4276194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 427747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 427847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 427947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 428047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 428147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 428247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 428347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 428447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 428547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 428647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 428747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 428847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 428947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 429047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 429147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 429247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 4293f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 4294f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 429547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 4296f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 4297f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 4298f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 429947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 4300194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 4301194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 4302194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 4303194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4304194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 4305194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 4306194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 43074ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 4308194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 4309194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 4310194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 431147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 431247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 431347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 4314fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 4315fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 4316fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4317fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 4318fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 4319fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 432019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 4321193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 4322193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 432319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 4324e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 4325189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 4326189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 4327a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 4328a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 4329a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 4330a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4331189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 4332a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 4333189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4334f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 4335f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 4336f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 4337f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 4338a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 4339a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 4340a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 4341a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4342a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 4343fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 4344fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 4345e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 4346e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 4347e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 4348e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 4349e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 4350e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 4351e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 4352e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 435316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4354e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 4355e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 4356e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 435716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4358e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 4359e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 4360e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 436147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 4362b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 436388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 436488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 4365f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 4366f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 436747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 436847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 4369194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 4370194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 4371194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 4372194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 4373fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 437416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4375c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 4376146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 4377fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 4378fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 43791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 4380ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 4381ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 4382ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 43831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 4384515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 43851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 4386515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 43871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 4388515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 43891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 4390515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 43911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 4392ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4393ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4394ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 43951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 4396ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 43971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 4398ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 4399ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 4400ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 4401ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 4402ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4403ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4404aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 4405ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4406ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 4407ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 440816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4409ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 4410ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 4411ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 4412b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4413ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4414ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4415ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4416b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4417ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 4418ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4419ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 44201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 4421515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 44221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 4423515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4424515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4425b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4426515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4427515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 4428515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 4429515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4430515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4431515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4432515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 44331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 4434515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 44351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 44366469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 44376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 44386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 44396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 44406469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 44416469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 44426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 44436469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 44446469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 44456469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 44466469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 44476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 44486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 44496469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4450515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4451515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4452b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4453515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 44546469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 44556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 44566469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 44576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 44586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4459642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 4460642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 4461642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 4462515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4463515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4464515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 44651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 4466515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 44671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 446818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4469515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 4470515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 447138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 447258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 4473b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 447458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 44759e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 4476515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4477515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 4478515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4479515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 448018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4481b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4482515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4483515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 4484515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4485515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4486515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4487515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 44881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 4489515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 44901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 449118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4492515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 4493515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 449418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 449558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 4496b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 449758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 4498b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4499515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4500515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 4501515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4502515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 450318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4504b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4505515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 450632869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 450798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 4508ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 450998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 451032869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 451198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 4512ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 451398447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 4514eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 45152a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 4516515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4517515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4518515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 451990b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 452090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 45219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 4522ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 452394b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 452494b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 452590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 4526ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 45273483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 45280692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 45290692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 45303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 4531