ARMAsmParser.cpp revision 9d39036f62674606565217a10db28171b9594bc7
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 { 2458462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 246d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 24789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITCondMask, 248fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 249fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 250cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 2519d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImmediate, 252706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 2538462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 2547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIndexRegister, 255584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 256a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 2578462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 2588d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 2590f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 2600f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 261e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 26292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 263580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImmediate, 2647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotateImmediate, 265293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach BitfieldDescriptor, 2668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 267a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 268a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 27024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 271a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2748462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2758462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2768462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 278fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 279fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 280fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 281fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 28289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 28389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 28489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 28589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 28689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 28789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 28889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 28989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 290a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 291a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 292a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 293a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 294584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 299a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3068155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 307cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 308cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 30916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3109d39036f62674606565217a10db28171b9594bc7Jim Grosbach struct { 3119d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned Val; // encoded 8-bit representation 3129d39036f62674606565217a10db28171b9594bc7Jim Grosbach } FPImm; 3139d39036f62674606565217a10db28171b9594bc7Jim Grosbach 3146a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 315a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 3177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 3187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 3197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 3207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 3217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 3220d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm; // shift for OffsetReg. 3237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 3250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 3260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 3277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 328f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 329f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 330f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 3317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 3327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 334580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 335e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 336580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 337e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 338e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 339e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 340e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 341e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 342af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 34392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 34492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 34592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 34692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 347af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 3487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 3497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 351293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 352293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 353293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 354293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 355a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 35616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 357146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 358146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 359762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 360762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 361762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 362762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 363762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 3648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 3658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 36789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ITCondMask: 36889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 36989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 370762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 3718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 372762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 373d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 374762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 375762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 376762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3778d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 3780f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 3790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 38024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 3818d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 382fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 383fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 384fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 385fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 386762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 387762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 388762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3899d39036f62674606565217a10db28171b9594bc7Jim Grosbach case FPImmediate: 3909d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImm = o.FPImm; 3919d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 392706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 393706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 394706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 395762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 396762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 397762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 3997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 4007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 401584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 402584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 403584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 404a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 405a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 4060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 407580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 408580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 4090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 410e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 411af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 412e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 41392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 414af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 41592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 4167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 4177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 4187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 419293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 420293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 421293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 422762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 423762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 42416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 425762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 426762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 427762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 428762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 429a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4308462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 4318462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 4328462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 4338462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4348462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 435fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 436fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 437fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 438fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 439fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 440a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 442a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 444a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 4466aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 4477729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 448a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 449a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4505fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 4510f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 4520f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 45324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 4548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 4558d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 456cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 457cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 458cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 459cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 460cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 4619d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned getFPImm() const { 4629d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(Kind == FPImmediate && "Invalid access!"); 4639d39036f62674606565217a10db28171b9594bc7Jim Grosbach return FPImm.Val; 4649d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 4659d39036f62674606565217a10db28171b9594bc7Jim Grosbach 466706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 467706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 468706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 469706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 470706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 471a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 472a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 473a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 474a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 475a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 476584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 477584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 478584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 479584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 480584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 481fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 482fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 4838462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 484d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 48589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool isITMask() const { return Kind == ITCondMask; } 48689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool isITCondCode() const { return Kind == CondCode; } 4873483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 4889d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isFPImm() const { return Kind == FPImmediate; } 489a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isImm8s4() const { 490a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (Kind != Immediate) 491a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 492a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 493a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!CE) return false; 494a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Value = CE->getValue(); 495a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 496a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 49772f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 49872f39f8436848885176943b0ba985a7171145423Jim Grosbach if (Kind != Immediate) 49972f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 50072f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 50172f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 50272f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 50372f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 50472f39f8436848885176943b0ba985a7171145423Jim Grosbach } 50572f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 50672f39f8436848885176943b0ba985a7171145423Jim Grosbach if (Kind != Immediate) 50772f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 50872f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 50972f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 51072f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 51172f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 51272f39f8436848885176943b0ba985a7171145423Jim Grosbach } 5136b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 5146b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 5156b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5166b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5176b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5186b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5196b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 5206b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 52183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 52283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 52383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 52483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 52583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 52683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 52783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 52883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 52983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 53083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 53183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 53283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 53383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 53483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 53583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 53683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 5377c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 5387c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (Kind != Immediate) 5397c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 5407c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5417c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 5427c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 5437c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 5447c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 545f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 546f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (Kind != Immediate) 547f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 548f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 549f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 550f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 551f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 552f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 5534a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 5544a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (Kind != Immediate) 5554a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 5564a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5574a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 5584a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 5594a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 5604a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 561fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 562fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 563fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 564fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 565fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 566fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 567fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 568fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 569ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 570ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 571ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 572ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 573ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 574ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 575ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 576ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 577ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 578ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 579ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 580ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (Kind != Immediate) 581ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 582ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 583ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 584ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 585ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 586ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 58770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 58870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (Kind != Immediate) 58970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 59070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 59170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 59270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 59370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 59470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 595f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 596f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 597f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 598f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 599f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 600f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 601f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 602f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 603f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 604f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 605f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 606f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 607f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 608f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 609f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 610f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 6116bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 6126bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 6136bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 6146bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6156bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 6166bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 6176bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 6186bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 6196b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 6206b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 6216b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 6226b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6236b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 6246b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 6256b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 6266b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 627c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 628c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Kind != Immediate) 629c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 630c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 631c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 632c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 633c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 634c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 635b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 6368d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 6370f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 6380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 63914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 640706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 64114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 642580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isShifterImm() const { return Kind == ShifterImmediate; } 643af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 644af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 6457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach bool isRotImm() const { return Kind == RotateImmediate; } 646293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach bool isBitfield() const { return Kind == BitfieldDescriptor; } 647f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; } 648f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 649f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 650f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 6517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemNoOffset() const { 6527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 653ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 6547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 6557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 656ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 6577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 6587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 659ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 6607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 6617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return true; 6627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 6637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 6667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 667039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 668039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Kind != Immediate) 669039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 670039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 671039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 672039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 673039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 674039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 675039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 6762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 6772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Memory) 6782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 6792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 6802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.ShiftType != ARM_AM::no_shift) return false; 6812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 6822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.OffsetRegNum) return true; 6832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 6842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetImm) return true; 6852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 6872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 6882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 6892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Immediate && Kind != PostIndexRegister) 6902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 6912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) 6922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 6932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 6942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 6962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 697251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 698251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 6992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 7017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 702ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 7037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 7047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return false; 7057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 7067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 7077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 7080da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 7090da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson Val == INT32_MIN; 7107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 7117f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBB() const { 7127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 7137f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Mem.ShiftType != ARM_AM::no_shift) 7147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7157f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7167f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBH() const { 7187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 7197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm != 1) 7207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7217f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7227f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 7247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum) 725ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 726ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 727ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 728ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach bool isT2MemRegOffset() const { 729ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative) 730ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 731ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach // Only lsl #{0, 1, 2, 3} allowed. 732ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach if (Mem.ShiftType == ARM_AM::no_shift) 733ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 734ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach if (Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm > 3) 735ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 736ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 737ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 7387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 7397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 7407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 7417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 7427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftType != ARM_AM::no_shift) 74387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 74460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return isARMLowRegister(Mem.BaseRegNum) && 74560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum)); 74660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 74760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 74860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 74960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 75060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 75160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 75260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (!Mem.OffsetImm) return true; 75360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 754ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 755ecd858968384be029574d845eb098d357049e02eJim Grosbach } 75638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 75738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 75838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 75938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 76038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 76138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (!Mem.OffsetImm) return true; 76238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 76338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 76438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 76548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 76648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 76748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 76848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 76948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 77048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (!Mem.OffsetImm) return true; 77148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 77248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 77348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 774ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 775ecd858968384be029574d845eb098d357049e02eJim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP) 776ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 777ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 778ecd858968384be029574d845eb098d357049e02eJim Grosbach if (!Mem.OffsetImm) return true; 779ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 780ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 781505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 782a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isMemImm8s4Offset() const { 783a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 784a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 785a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate offset a multiple of 4 in range [-1020, 1020]. 786a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!Mem.OffsetImm) return true; 787a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 788a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 789a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 790b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach bool isMemImm0_1020s4Offset() const { 791b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 792b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return false; 793b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // Immediate offset a multiple of 4 in range [0, 1020]. 794b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach if (!Mem.OffsetImm) return true; 795b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 796b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 797b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 7987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 7997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 800f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 8017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 8027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 8037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 8044d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson return (Val == INT32_MIN) || (Val > -256 && Val < 256); 805f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 806f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach bool isMemPosImm8Offset() const { 807f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 808f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return false; 809f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach // Immediate offset in range [0, 255]. 810f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach if (!Mem.OffsetImm) return true; 811f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 812f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return Val >= 0 && Val < 256; 813f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 814a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemNegImm8Offset() const { 815a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 816a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 817a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [-255, -1]. 818a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach if (!Mem.OffsetImm) return true; 819a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 820a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return Val > -256 && Val < 0; 821a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 822a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemUImm12Offset() const { 823a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 824a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 825a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // and we reject it. 826a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) 827a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return true; 828a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 829a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 830a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 831a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [0, 4095]. 832a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach if (!Mem.OffsetImm) return true; 833a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 834a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return (Val >= 0 && Val < 4096); 835a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 8367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 83709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 83809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 83909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 84009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) 84109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 84209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 8437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 844ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 8457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 8467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 8477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 8480da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 8497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 8507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 8517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Immediate) 8527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 8537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 854ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 8557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 85663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 857ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 859584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 860a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 8613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 8623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 86314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 86414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 86514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 86614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 8673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 8683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 8693483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 8703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 8713483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 8728462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 873345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 8748462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 87504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 87604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 8778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 8788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 879fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 880fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 881fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 882fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 883fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 88489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 88589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 88689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 88789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 88889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 88989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 89089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 89189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 89289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 89389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 894fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 895fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 896fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 897fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 898fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 899d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 900d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 901d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 902d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 903d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 904a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 905a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 906a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 907a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 908a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 909af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 910e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 911af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 912af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 913af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 914e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 915af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 916e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 917e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 918af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 919152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 920af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 921af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 92292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 923af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 92492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 92592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 926580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 9270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 928580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 929580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 9300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 9310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 93287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 9337729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 9345fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 9355fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 9367729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 9377729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 93887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 93987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 9400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 9410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 9420f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 9430f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9440f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 9450f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 9460f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 9470f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 9497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 9517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 9527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 9537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 954293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 955293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 956293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 957293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 958293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 959293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 960293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 961293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 962293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 963293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 964293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 9653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 9666b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9676b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 9686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 9696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 9709d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 9719d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9729d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 9739d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 9749d39036f62674606565217a10db28171b9594bc7Jim Grosbach 975a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 976a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 977a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 978a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 979a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 980a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 981a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 982a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 98372f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 98472f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 98572f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 98672f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 98772f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 98872f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 98972f39f8436848885176943b0ba985a7171145423Jim Grosbach } 99072f39f8436848885176943b0ba985a7171145423Jim Grosbach 99172f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 99272f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 99372f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 99472f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 99572f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 99672f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 99772f39f8436848885176943b0ba985a7171145423Jim Grosbach } 99872f39f8436848885176943b0ba985a7171145423Jim Grosbach 9996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 10006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 10026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 10036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 100483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 100583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 100683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 100783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 100883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 100983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 10107c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10117c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 10127c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 10137c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 10147c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 101583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 101683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 101783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 101883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 1019f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1020f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1021f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1022f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1023f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1024f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1025f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1026f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 10274a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 10284a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10294a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 10304a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 10314a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10324a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 10334a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 10344a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 1035fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 1036fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1037fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 1038fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 1039fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 1040ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 1041ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1042ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 1043ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 1044ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 1045ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 1046ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1047ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 104870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 104970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 105070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 105170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 105270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 105370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 105470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 105570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 105670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1057ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1058ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1059f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 1060f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1061f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 1062f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1063f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1064f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1065f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1066f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1067f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1068f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1069f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1070f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1071f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1072f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 10736bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 10746bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10756bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 10766bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 10776bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 10786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 10793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 10803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 10813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 108216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1083c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 1084c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1085c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 1086c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1087c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1088706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1089706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1090706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1091706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1092706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 10937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 10947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1096505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1097505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 10987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 10997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 11007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 11017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetRegNum) { 11027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 11037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 11047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 11057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 11067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 11077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 11087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 11097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 11107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 1111dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 1112ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 11137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 11147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 11157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1116ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1117ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1118039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1119039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1120039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1121039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1122039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1123039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1124039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1125039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1126039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1127039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1128039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1129039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1130039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1131039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 11322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 11332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 11342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 11352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetRegNum) { 11362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 11372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 11382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 11392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 11402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 11412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 11422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 11432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 11442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 11452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 11462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 11472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 11482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 11492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 11502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 11512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 11522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 11532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) { 11542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 11552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 11562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 11572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1158251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 11592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 11602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 11612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 11622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 11632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 11642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 11652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 11662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 11672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1168251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 11692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 11702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 11712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 11722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 11737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 11747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 11757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 11767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 11777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 11787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 11797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 11807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 11817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 11827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 11837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 11847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 11857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1186a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1187a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1188a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 1189a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1190a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1191a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1192a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1193b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1194b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1195b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1196b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 1197b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1198b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1199b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1200b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 12017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 12027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 12037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 12047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1206ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1207ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1208f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1209f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1210f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1211f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1212a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1213f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1214a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1215a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1216a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1217a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1218a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 1219a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach if (Kind == Immediate) { 1220a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1221a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1222a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1223a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1224a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1225a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1226a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 1227a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1228a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1229a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1230a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 12317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 12327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 123309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 123409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate) { 123509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 123609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 123709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 123809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 123909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 124009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 12417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 12427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 124592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 12467f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 12477f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 12487f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12497f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 12507f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 12517f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 12527f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 12537f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 12547f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12557f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 12567f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 12577f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 12587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 12597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 12607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 12610d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 12627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 12647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1266d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1267ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1268ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1269ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1270ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 1271ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach Inst.addOperand(MCOperand::CreateImm(Mem.ShiftImm)); 1272ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1273ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 12747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 12757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 12767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 127814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 12793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 128060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 128160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 128260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 128360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 128460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 128548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 128648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 128738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 128838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 128938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0; 129038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 129138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 129238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 129338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 129448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 129548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 129648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0; 129748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 129848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 129960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 130060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1301ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1302ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1303ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 1304ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1305ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1306ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1307ecd858968384be029574d845eb098d357049e02eJim Grosbach 13087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 13097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 13117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 13127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 13137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 131463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 13157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 13167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1317f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1318ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 13197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 13207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 13217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1322f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1323f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1324f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1325f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1326f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1327f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1328f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1329f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1330f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1331f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1332f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1333f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1334ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1335ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1340584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1341a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1342a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1343a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1344a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1345a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1346b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1347b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 134889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 134989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARMOperand *Op = new ARMOperand(ITCondMask); 135089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 135189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 135289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 135389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 135489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 135589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 13563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 13573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 1358345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1359345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1360345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 13613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1362345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1363345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1364fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 1365fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 1366fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1367fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1368fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1369fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1370fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1371fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1372fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 1373fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 1374fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1375fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1376fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1377fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1378fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1379fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1380d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 1381d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 1382d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1383d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1384d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1385d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1386d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1387d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 13883a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 13893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 1390762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1391762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1392762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1393762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 13943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1395a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1396a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 139750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 13983a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 1399762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1400762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1401762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 14023a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1403a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1404a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1405e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1406e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1407e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1408e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1409e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 1410e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 1411af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1412af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1413af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1414af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1415e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1416e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1417e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1418e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1419e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 142092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 142192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 142292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 142392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 142492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 1425af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1426af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1427af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 142892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 142992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 143092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 143192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 143292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1433580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 14340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 1435580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ARMOperand *Op = new ARMOperand(ShifterImmediate); 1436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1437580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 14380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 14390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 14400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 14410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 14420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 14447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach ARMOperand *Op = new ARMOperand(RotateImmediate); 14457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 14467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 14477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 14487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 14497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 14507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1451293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1452293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 1453293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 1454293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1455293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1456293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1457293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1458293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1459293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1460293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 14617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 14625fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1463cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 14640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 14650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1466d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 14670f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 1468d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1469275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 14700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 14710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 14720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 14735fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 14747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 147524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1476cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1477cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1478cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 14798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 14808d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 14818d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 14823a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 14833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 1484762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1485762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1486762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 14873a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1488cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1489cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 14909d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 14919d39036f62674606565217a10db28171b9594bc7Jim Grosbach ARMOperand *Op = new ARMOperand(FPImmediate); 14929d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 14939d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 14949d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 14959d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 14969d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 14979d39036f62674606565217a10db28171b9594bc7Jim Grosbach 14987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 14997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 15007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 15017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 15020d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 15037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 15043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 15053a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 1506762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 15077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetImm = OffsetImm; 15087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetRegNum = OffsetRegNum; 1509762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 15100d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Op->Mem.ShiftImm = ShiftImm; 15117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.isNegative = isNegative; 15127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 15137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 15147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 15157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 151616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1517f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1518f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1519f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 15207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 15217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARMOperand *Op = new ARMOperand(PostIndexRegister); 15227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1523f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1524f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1525f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1526762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1527762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 15283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1529a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1530706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1531706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1532706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1533706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1534706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1535706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1536706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1537706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1538a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1539a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1540a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1541a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1542a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1543a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1544a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1545a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1549584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1550584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1551584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1552584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1553584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1554a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1555a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1556a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1557a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1558b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1559fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 15609d39036f62674606565217a10db28171b9594bc7Jim Grosbach case FPImmediate: 15619d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 15629d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 15639d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 1564fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 15656a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1566fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1567d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1568d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1569d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 157089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ITCondMask: { 157189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)", 157289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)", 157389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(tee)", "(eee)" }; 157489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 157589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 157689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 157789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 1578fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1579fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1580fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1581fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1582fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1583fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1584584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1585584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1586584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1587fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1588fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1589fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1590706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1591706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1592706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1593fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 15946ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 15957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << " base:" << Mem.BaseRegNum; 15966ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1597fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 15987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 1599f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1600f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1601f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1602f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1603f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1604f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 16057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 1606a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1607a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1608a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1609a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1610a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1611a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1612a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1613a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1614a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1615fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 161650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1617fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1618580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 1619580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1620580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1621e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1622e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 162392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1624af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1625af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1626af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1627af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1628e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 16290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 163092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 163192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1632af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1633af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1634af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 163592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 163692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 16377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 16387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 16397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 1640293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 1641293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1642293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1643293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 16440f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 16450f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 16460f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 16478d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 16488d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 16495fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 16505fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 16517729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 16527729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 16537729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 16548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 16558d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 16568d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 16578d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 16588d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1659fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1660fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1661fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1662fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1663fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 16643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 16653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 16663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 16673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 16683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 16693483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 16703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 16713483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 167269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 167369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 16741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1675bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1676bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1677bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1678bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 16799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1680e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1681e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 16823a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 16831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 168418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 16857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1686d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1688a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 16890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 16900c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 16910c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 16920c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 16930c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 16940c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 16950c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 16960c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 16970c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 16980c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 16990c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 17000c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 170169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1702b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1703e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1704e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1705d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 170619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 170719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 170819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 170919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 171019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 17110d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 17120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 17130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 17140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 17150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 17160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 17170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 17180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 17190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 17200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 17210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 17220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 17230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 17240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 17250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 17260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 17270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 172819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 17290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1730e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1731e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1732e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1733e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1734e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1735eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1736e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1737e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1738e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1739e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1740e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1741e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1742e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1743e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1744e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1745e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1746e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1747e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1748e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1749e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1750e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1751e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 175219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 175319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 175419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 175519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1756e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1757e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 175819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 175919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 176019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 176119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1762e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1763e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1764e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1765e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1766e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1767e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1768e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 176919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 177019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1771e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1772e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 17731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1774e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 177519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 177619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 177719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 177819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 177919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 178019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1781e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 178219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 178319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1784e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1785e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 178692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 178792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1788af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 17890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 179092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 179192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 179292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 17930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 179419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 17950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 17960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 17970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 179850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 179950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 180050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1801e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1802e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1803e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 180450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 18051355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1806e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 18071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1808e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 180950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1810d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 181150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1812a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1813e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1814e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 181550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 181650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1817e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 181899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 181999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 182050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1821a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1822a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1823fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1824fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1825fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1826fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1827e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1828e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1829e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1830e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1831e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1832fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1833e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1834e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1835e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1836e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1837e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1838e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1839e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1840e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1841e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1842e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1843e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1844e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1845e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1846e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1847e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1848e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1849fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1850e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1851e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1852e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1853e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1854e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1855e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1856e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1857e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1858e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1859e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1860e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1861e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1862e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1863e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1864e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1865e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 186689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 186789df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 186889df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 186989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 187089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 187189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 187289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 187389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 187489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 187589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 187689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 187789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 187889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 187989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 188089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 188189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 188289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 188389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 188489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 188589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 188689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 188789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 188889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 188989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 189089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 189189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 189289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 189389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 189489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 189589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 189689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 189789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 189889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 189989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 190089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 190143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1902fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1903fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1904f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 190543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1906e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1907e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1908e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1909e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1910fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1911e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1912f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1913e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1914e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1915fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1916f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1917fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1918fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 191943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1920fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1921fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1922f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 192343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1924fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1925fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1926fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1927fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1928fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1929fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1930f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1931fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1932fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1933fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1934f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1935e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1936e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1937d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 1938d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 1939d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 1940d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 1941d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 1942d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 1943d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 1944d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 1945d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 1946d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 1947d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 1948d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 1949d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 1950d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 1951d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 1952d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 1953d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 1954d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 1955d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 1956d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 1957d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 1958d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 1959d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 196050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 19611355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 196218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1963a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1964e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 1965d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 1966d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 196716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1968d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 1969d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 1970d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 1971d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 1972d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 1973d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 1974d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach MCRegisterClass *RC; 1975d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 1976d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 1977d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 1978d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 1979d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 1980d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 1981d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 1982d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 1983e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1984d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 1985d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // space for that many. 1986d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 1987d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Store the first register. 1988d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 1989d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 1990d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 1991d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 1992d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 1993d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 1994d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 1995d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 1996d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 1997d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 1998d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 1999d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2000d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2001d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2002d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2003d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2004d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2005d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2006d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2007d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2008d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2009d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2010d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2011d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2012d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2013d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2014d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2015d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2016d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2017d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2018d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2019d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2020d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2021d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2022d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2023d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 20242d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2025d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2026d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2027d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2028d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2029d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg)) 2030d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2031d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2032d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2033d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2034d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2035d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2036d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2037d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2038d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2039d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2040d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2041d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2042d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2043d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2044e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 204550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 204650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2047d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2048d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 204943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2050f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 205143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2052706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2053706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2054706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2055706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 2056706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2057706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2058706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 2059706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 2060032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 2061706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 2062032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 2063706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 2064706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 2065032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 2066706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 2067032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 2068706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 2069706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 2070706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 2071706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2072706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 2073f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2074706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2075706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2076706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2077f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2078706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 2079706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 208043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2081a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 208243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2083a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2084a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2085a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2086a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 2087a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2088a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 2089a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 2090a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 2091a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 2092a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 2093a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 2094a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2095a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2096a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 2097a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 2098a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 2099a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 2100a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2101a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 2102a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2103a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2104a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2105a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2106a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 2107584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 2108584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 210943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2110584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 211143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2112584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2113584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2114584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2115584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 2116584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2117acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 2118acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 2119acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2120acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 2121acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 2122acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 2123acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 2124acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 2125acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 2126acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 2127acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 2128acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 2129acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 2130acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 2131acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 2132acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 2133acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 2134acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 2135acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2136acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 2137acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2138acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2139acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 2140acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 2141acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2142acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2143acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 2144acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2145acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 2146acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 2147acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2148584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 2149584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 2150584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 2151b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 2152584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 2153584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 2154584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2155584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 2156584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 2157584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2158584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 2159584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2160584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 2161584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 2162b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 2163584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 2164584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 2165584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2166584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 21674b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 2168584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 2169584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2170584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 2171bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 21724b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 2173584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 217456926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 217556926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 2176584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 2177584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 2178584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 2179584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 2180584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 2181584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 2182584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2183584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2184584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 2185584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 2186584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 2187584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2188584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 2189584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2190584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 2191584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2192584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2193584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 2194584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 2195584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 2196584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2197584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2198584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 2199584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 2200584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2201584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2202584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2203584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 2204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 2205a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2206f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2207f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 2208f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 2209f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2210f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2211f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2212f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2213f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2214f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 2215f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 2216f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 2217f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 2218f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2219f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2220f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2221f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 2222f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2223f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 2224f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2225f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2226f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2227f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2228f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 2229f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2230f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 2231f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 2232f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2233f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 2234f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2235f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2236f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2237f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 2238f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 2239f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2240f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2241f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 2242f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 2243f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 2244f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2245f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2246f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2247f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 2248f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2249f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 2250f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 2251f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2252c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2253c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2254c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2255c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 2256c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2257c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2258c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2259c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2260c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 2261c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 2262c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 2263c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 2264c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 2265c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2266c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 2267c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2268c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2269c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2270c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 2271c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 2272c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 2273c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 2274c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 2275c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2276580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 2277580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 2278580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 2279580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 2280580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 2281580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2282580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2283580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 2284580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 2285580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2286580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2287580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2288580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2289580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 2290580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 2291580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 2292580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 2293580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 2294580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 2295580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 2296580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2297580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2298580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2299580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 2300580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2301580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 2302580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2303580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2304580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2305580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2306580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 2307580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2308580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 2309580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2310580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2311580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 2312580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2313580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2314580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2315580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 2316580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 2317580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2318580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2319580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2320580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 2321580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 2322580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2323580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 2324580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 2325580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2326580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 23270afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 23280afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 23290afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 23300afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 23310afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 2332580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 2333580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 2334580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2335580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 2336580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 2337580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2338580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2339580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2340580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2341580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 2342580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 2343580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2344580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 2345580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 2346580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 23477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 23487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 23497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 23507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 23517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 23537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 2354326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2355326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 23567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 2357326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 2358326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 23597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 23607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 23617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 23627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 23637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 23647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 23657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 23667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 23677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 23687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 23697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 23707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 23717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 23727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 23737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 23747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 23757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 23767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 23777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 23787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 23797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 23807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 23817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 23827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 23837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 23847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 23857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 23867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 23877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 23887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 23897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 23907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 23917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 23927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 23937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 23947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2395293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2396293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2397293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2398293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2399293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2400293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2401293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2402293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2403293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2404293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2405293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2406293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2407293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2408293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2409293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2410293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2411293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2412293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2413293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2414293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2415293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2416293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2417293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2418293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2419293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2420293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2421293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2422293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2423293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2424293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2425293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2426293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2427293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2428293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2429293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2430293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2431293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2432293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2433293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2434293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2435293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2436293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2437293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2438293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2439293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2440293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2441293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2442293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2443293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2444293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2445293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2446293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2447293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2448293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2449293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2450293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2451293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2452293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2453293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2454293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2455293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2456293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2457293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2458293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2459293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2460293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 24617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 24627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 24637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2464f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2465f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2466f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 24677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 24687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 24697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 24707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 24717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 24727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 24737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 247416578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 24757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 24767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 24777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 24787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 24797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 24807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 248116578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 24827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 24837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 24847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 24857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 24867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 24877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 24887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 24897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 24907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 24917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 24927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 24937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2494f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2495f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 24960d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 24970d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 24980d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 24990d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 25000d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2501f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2502f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2503f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 25047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 25057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 25067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 25077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2508251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2509251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2510251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2511251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2512251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2513251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2514251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2515251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2516251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2517251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2518251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2519251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2520251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2521251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2522251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2523251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2524251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2525251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2526251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2527251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2528251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2529251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2530251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2531251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2532251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2533251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2534251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2535251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2536251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2537251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2538251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2539251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2540251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2541251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2542251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2543251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2544251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2545251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2546251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2547251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2548251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2549251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2550251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2551251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2552251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2553251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2554251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2555251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2556251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2557251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2558251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2559251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2560251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2561251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2562251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2563251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2564251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2565251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2566251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2567251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2568251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2569251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2570251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2571251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2572251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2573251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 2574251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2575251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2576251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 2577251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2578a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 2579a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2580a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2581a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 2582a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 2583a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2584a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 2585a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2586a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2587a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 2588a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 2589a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 2590a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 2591a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 2592a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2593a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 2594a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 2595a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 2596a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 2597a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2598a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2599a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 2600a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 2601a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2602a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 2603a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 2604a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 2605a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2606a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2607a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 2608a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 2609a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 2610a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2611a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 2612a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 2613a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 2614eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 2615eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2616eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2617eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 2618eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 2619eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2620eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2621eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2622eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 2623eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2624eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2625eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 2626eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2627eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 2628eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 2629eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2630ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 2631ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2632ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2633ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 2634ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 2635ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2636ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 2637ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2638ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2639ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 2640ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2641ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 2642ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 2643ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 26441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2645ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2646ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2647ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 26481355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2649ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2650ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2651ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2652ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2653ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2654ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 26557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2656ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2657ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2658ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2659ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 26609ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 26619ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 26629ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 26639ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 26649ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 26659ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 26669ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 26679ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 26689ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 26699ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 26709ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 26719ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 26729ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 26739ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 26749ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 26759ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 26769ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 2677548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2678548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2679548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2680548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 2681548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2682548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2683548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 2684548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2685548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2686548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2687548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2688548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 2689548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 2690548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 26911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2692ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2693ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2694ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 26951355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2696ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2697ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2698ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2699548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2700548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2701548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 27027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 27037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 27047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 27057b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 27067b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 27077b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 27087b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 27097b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 27107b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 27117b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 27127b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 27137b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 27147b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 27157b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 27167b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 27177b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 27187b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 27197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 27207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 27217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 27227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 27237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 27247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 27257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2726ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 27277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 27287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 27297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 27307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 27317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 27327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 27337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2734ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2735ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2736ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2737ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 27387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2739ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2740ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2741ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 27427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 27437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 27447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2745aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2746ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2747ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 27487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 27497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 27507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 27517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 27527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 27537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 27547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 27557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 2756aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 27577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 27587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 27597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 27607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 27617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 27627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 27637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 27647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 27657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 27667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 27677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 27687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 27697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 27707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 27717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2772ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2773ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2774ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2775ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 27767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2777ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2778ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2779ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 27807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 27817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2782ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2783ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 27847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2785ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 27867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 27877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 27887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 27897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 27907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2791ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2792ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2793ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2794ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 27952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 27962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 27972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 27982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 27992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 28002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 28022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 28032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 28042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 28052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 28062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 28072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 28082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 28092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 28102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 28112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 28122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 281314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 281414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 281514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 281614605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 281714605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 281814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 281914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 282014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 282114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 282214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 282314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 282414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 282514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 282614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 282714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 282814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 282914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 283014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 2831623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2832623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2833623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2834623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 2835623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2836623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2837623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2838623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 2839623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2840623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2841623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2842623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 2843623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 2844623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 284588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 284688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 284788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 284888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 284988ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 285088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 285188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 285288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 285388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 28547a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 28557a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 28567a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 28577a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 285888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 28597a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 286088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 286188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 286288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 286388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 286488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 28657a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // If we have a three-operand form, use that, else the second source operand 28667a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // is just the destination operand again. 28677a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach if (Operands.size() == 6) 28687a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 28697a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach else 28707a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach Inst.addOperand(Inst.getOperand(0)); 287188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 287288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 287388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 287488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 2875623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2876e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 28779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 287850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 28797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2880762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 288118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 2882a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 2883762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2884b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 2885a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 288618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 28871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 28887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 28897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 2890a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 28910571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 28920571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 28930571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 28947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 28950571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 28967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 2897762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 2898b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 2899a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 29007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 29017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, false, S, E)); 290203f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 2903fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 2904fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 2905fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 2906fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2907fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 2908fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 2909fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 29107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 29117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 291250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 29137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 29147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 291550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 29167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If we have a '#' it's an immediate offset, else assume it's a register 29177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 29187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 29197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 29207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 292150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 29220da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 29237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 29247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 29257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 292605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 29277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 29287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 29297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 29307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 29317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 29327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 29337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 29340da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 29350da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 29360da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 29370da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 29380da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 29397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 29407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 29417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 29427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 29437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 294405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 29457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 29467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 29477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 29487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::no_shift, 0, false, S,E)); 2949a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 29507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 29517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 29527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 29537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 29547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 2955762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 29567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 29577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 29589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 2959d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 29607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 29617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 29627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 29637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 29647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 29657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 29667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 29677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 29687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 29699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 29707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 29717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 29727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 29737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 29747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 29757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 29767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 29770d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 29787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 29797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 29800d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 29817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 29829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 298316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 29847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 29857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 29867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 29877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 29887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 29897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 29907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 29910d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach ShiftType, ShiftImm, isNegative, 29927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 29937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2994f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 2995f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 2996f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 2997f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2998f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 2999f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 30009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 30019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 30029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 30039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 30047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 3005a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 3006a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 30077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 30087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 30097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 30107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 301118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3012a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3013a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 301438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 3015a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 30160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 3017a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 30180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 3019a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 30200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 3021a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 30220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 3023a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 30240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 3025a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 30267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 3027b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 3028a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 30307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 30317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 30327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 30337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 30347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 30357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 30367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 30377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 30389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 30397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 30407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 30417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 30427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 30437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 30447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 30457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 30467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 30477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 30487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 30497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 30507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 30517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 30527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 30537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 30547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 3055a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3056a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 3057a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3058a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30599d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 30609d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 30619d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 30629d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 30639d39036f62674606565217a10db28171b9594bc7Jim Grosbach 30649d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) 30659d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 30669d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 30679d39036f62674606565217a10db28171b9594bc7Jim Grosbach 30689d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 30699d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 30709d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 30719d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 30729d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 30739d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 30749d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 30759d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 30769d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 30779d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 30789d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 30799d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 30809d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 30819d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 30829d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 30839d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 30849d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 30859d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 30869d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 30879d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 30889d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 30899d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 30909d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 30919d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 30929d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 30939d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 30949d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 30959d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 30969d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 30979d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 30989d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 30999d39036f62674606565217a10db28171b9594bc7Jim Grosbach 31009d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 31019d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 31029d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 31039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 31049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 31051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3106fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 3107762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 3108fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3109fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 3110fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 3111f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 3112f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 3113fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 3114f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 3115f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 3116f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 3117f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 3118f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 3119fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3120a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 3121146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 3122146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 312350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 312419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 31255cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 31261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 312750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 31280d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 312919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 31300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 313119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 313219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 31335cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 31345cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 31355cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 31365cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 31375cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 31385cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 3139e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 3140e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 3141e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 314219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 314367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 314467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 3145515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 3146515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 3147515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 3148762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3149515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 315050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 3151762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 315250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 315350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 315450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 3155a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 31561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 3157d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 31581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 315963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 3160079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 3161079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 3162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3163b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 316463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 3165515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 3166515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 316750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 316863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 316963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (!CE) { 317063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson Error(S, "constant expression expected"); 317163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return MatchOperand_ParseFail; 317263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 317363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson int32_t Val = CE->getValue(); 317463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (isNegative && Val == 0) 317563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 3176762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 317750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 317850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 317963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 31809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 31819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 31827597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 31837597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 31847597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 31851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 31869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 31879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 31887597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 31897597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 31909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 31919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 31927597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 31937597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 31949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 31957597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 31969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 31979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 3198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 32011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 32027597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 32031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 32047597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 32059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 32069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 32078a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 32089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 32099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 32109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 32119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 32129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 32139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 32149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 32159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 32169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 32177597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 32189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 32197597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 32209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 32219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 32229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 32239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 32249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 32259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 32269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 32279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 32289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 32299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 32309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 32319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 32329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 32339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 3234352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 3235352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 3236352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 3237badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 323889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 32391355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 32405f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 32415f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 324289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 324389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 3244352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 3245352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 3246a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 3247352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3248badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 3249352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 3250352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 32515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 32525f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 32535f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 32545f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 32555f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 32565f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 32575f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 32585f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 3259352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3260badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 32613f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 32623f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 3263ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 326471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 326504d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 32662f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 32673f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 32683f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 32693f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 32703f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 32713f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 32723f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 32733f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 32743f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 32753f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 32763f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 32773f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 32783f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 32793f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 32803f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 32813f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 32823f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 32833f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 32843f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 32853f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 32863f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 32873f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 32883f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 32893f00e317064560ad11168d22030416d853829f6eJim Grosbach } 329052925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 3291345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3292352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 3293352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 3294352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 329500f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 32965f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 32975f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 32985f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 3299e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 3300e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 3301352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 3302352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 3303352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 3304352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3305a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 3306a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 3307a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 3308a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 3309a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 3310a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 3311a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 3312a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 3313a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 3314a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 3315a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 3316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 3317a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 332089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 332189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 332289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 332389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 332489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 332589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3326352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3327352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 33283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 33293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 33303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 33313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 33323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 3333fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 33341355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 3335fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 3336eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 3337eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 33383443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 3339eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 3340d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 3341eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 3342d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 33433443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 3344d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 3345d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 3346eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 3347fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 3348eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 33493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 3350eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 3351eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 3352eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 3353eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 3354ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 3355ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 33560780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 33574af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw") && 33584af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 33594af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 33604af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 33611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 33623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 3363fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 33643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 3365fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 3366fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 3367fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 336863b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 3369fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 3370fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 3371badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 3372badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3373d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 3374d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 337520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 337620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 3377d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3378d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 3379d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 3380d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 3381d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 3382d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 3383d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 3384d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 3385d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 33868adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 3387d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 3388d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 3389d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3390d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 33913912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 33923912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 33933912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 33943912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 33953912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 33963912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 33973912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 33983912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 339972f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 340020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 340120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 340220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 3403f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 3404f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 3405f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 340672f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 340772f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 340872f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 340920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 341020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 341120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 341272f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 3413f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 3414f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 341520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 341620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 341720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 3418f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 3419f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 342020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 342120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 342220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 342320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 342420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 342520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 342620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 342720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 342820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 342920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 343020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 343120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 343220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 343320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 343420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 343564944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 343620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 343720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 343820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 343920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 344020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 344120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 344220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 344320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 344420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 344564944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 344664944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 344764944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 344864944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 344964944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 345064944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 345164944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 345264944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 345364944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 345464944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 345564944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 345664944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 345764944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 345864944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 345964944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 346064944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 346164944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 346264944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 346364944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 346464944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 346564944f48a1164c02c15ca423a53919682a89074cJim Grosbach 346664944f48a1164c02c15ca423a53919682a89074cJim Grosbach 346720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 3468f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 3469f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 3470f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 3471f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 3472f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 3473f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 3474f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 347572f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 347672f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 347772f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 347872f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 34793912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 3480d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 3481d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 3482d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3483badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 3484badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 3485badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3486badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 3487badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 3488ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 3489badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3490352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 3491352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 3492a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 3493352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 349489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 34951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 349689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 3497badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 34980c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 34990c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 35000c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 35010c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 35020c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 35030c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 3504ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 3505ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 350689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 350789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 350889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 350989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 351089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 351189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 3512f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 3513f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 3514f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 3515f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 3516f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 351789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 351889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 351989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 352089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 352189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 3522f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 352389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 352489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 352589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 352689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 352789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 3528f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 352989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 353089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3531ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 3532ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 35339717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 35343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 35353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 35363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 35373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 35383771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 35393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 35403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 35413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 35421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 35433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 354433c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 354533c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 354633c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 354733c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 3548ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 354933c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 355033c16a27370939de39679245c3dff72383c210bdJim Grosbach } 3551c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 3552c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 3553c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 3554c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 3555c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 3556c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 3557c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 355833c16a27370939de39679245c3dff72383c210bdJim Grosbach 35593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 3560f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 3561f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 35623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 3563f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 3564f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 35653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 35663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 35673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 3568f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 3569f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 35703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 3571f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 3572badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 3573345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3574a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 3575a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 3576a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 3577a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 3578a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 3579a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3580a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3581345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 35825747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 35835747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 35845747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 3585a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 3586a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 35874d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // For now, we're only parsing Thumb1 (for the most part), so 35884d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // just ignore ".n" qualifiers. We'll use them to restrict 35894d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // matching when we do Thumb2. 359081d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 359181d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 359281d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 359381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 35945747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 35955747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 35965747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 35975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 3598a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 35991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3600cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3601cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3602cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3603a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3604a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 3605b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 3606a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 36081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3609cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3610cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3611cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3612a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3613a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 361416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3615cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 3616cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 361734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 3618cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3619146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 362034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 3621ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3622d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 3623d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 3624d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 362520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 362620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 362720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 362820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 362920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 3630ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3631ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 3632ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 3633ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 3634ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3635cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 3636cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 3637cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 3638cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // a CondCode operand in the list. If we're trying to match the label 3639cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // version, remove the CondCode operand here. 3640cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 3641cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 3642cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3643cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 3644cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 3645cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 3646857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 3647857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 3648857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 3649857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 3650857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 3651857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 3652857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3653857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3654857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3655857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 3656857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 3657857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 365868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 365968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 366068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 366168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 366268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 366368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 366468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 366568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 366668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 366768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 366868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3669857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 3670857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3671857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3672934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 3673934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 3674934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 3675934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3676934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3677934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3678934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 3679934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 3680934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3681934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 3682934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3683934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3684934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 36859898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 3686ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3687ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3688189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 3689aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3690aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 3691aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 3692aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 3693aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 3694aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 3695aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 3696aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 3697aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 3698aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 3699aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 3700aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 3701aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 3702aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 3703aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 3704aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 3705aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 3706aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 370776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 370876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 370976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 371076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 371176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 371276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 371376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 371476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 371576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 371676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 371776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 3718f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 3719f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 3720f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 3721f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 3722f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[]; 3723f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 3724f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 3725f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 3726f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 3727f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 3728189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 3729189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 3730189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 3731189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3732f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 3733f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 3734f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 3735b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 3736b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 3737b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 3738b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 3739f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 3740f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 3741f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 3742f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 3743a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 3744f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 3745f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 3746f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 3747f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 3748f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 3749f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 3750f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 3751f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 3752f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 3753f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 3754f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 3755f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 3756f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 3757f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 3758f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 3759f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 3760f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 3761c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 3762f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 3763f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 376451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 376551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 3766f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 3767f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 3768189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 37692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 37702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 37712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 3772189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 3773189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3774189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 3775189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3776189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 3777189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 3778189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 3779189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3780189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 378114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 378214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 378314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 378414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 378514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 378614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 378714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 378814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 378914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 379053642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 379153642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 3792189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 3793189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3794189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3795189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 3796189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 379714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 3798189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 3799189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3800189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3801fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 3802fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 3803fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 3804fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 3805fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 3806fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 3807fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 3808fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 380900c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 3810fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 381193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 381276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 381376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 381476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 381576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 381676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 381793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 381893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 381993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 38207260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 38217260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 38227260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 3823aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 382476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 3825aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 3826aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 382793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 382876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 382993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 383093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 383176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 383276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 3833aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 38347260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 38357260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 38367260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 383793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 383893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 383993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 384076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 384176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 384276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 384376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 384476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 384576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 384676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 38476dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 3848aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3849aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 3850aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3851aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 38526dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 38536dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 38546dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 3855aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3856aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 3857aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3858aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 38596dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 38606dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 38611e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 38621e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 38638213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 38641e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 38651e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 38661e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 38671e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 3868189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3869189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3870189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3871189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 3872189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3873f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 3874f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 3875f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3876f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 3877f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 3878f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 3879f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 3880f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 3881f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 3882f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 3883f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 3884f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3885f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3886f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 3887f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 3888f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 3889f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3890f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3891f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 3892f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3893f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 3894f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 3895f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 3896f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 3897f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 3898f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 3899f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 3900f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 3901f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3902f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3903f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 3904f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 3905f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3906f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3907f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 3908f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 3909f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 391089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 39110f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 39120f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 39130f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 39140f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 39150f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 391689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 391789e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 3918f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 3919f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 3920f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 3921f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 3922f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 3923f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 3924f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 3925f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 392651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 392751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 392851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 392951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 393051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 393151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 393251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 393351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 393451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 393551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 3936c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 3937a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 3938a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) 3939c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 3940c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 3941395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 3942395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 3943395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) 3944395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 39453ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 394676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 394776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 394876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 394976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 395076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 395176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 395276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 395376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 395476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 395576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 395676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 395776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 395876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 395976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 396076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 396176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 396276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 396376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 396476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 396576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 396676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 396776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 396876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 396976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 39708213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 39718213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 39728213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 39738213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 39748213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 39758213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 39768213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 39778213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 39788213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 39798213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 39808213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 39818213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 39828213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 39831ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 39841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 39851ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 39861ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 39871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 3988c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 3989c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 3990c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 39911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 39921ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 39931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 39941ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 39951ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 39961ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 39971ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 39981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 39991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 40001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 40011ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 40021ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 40031ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 40041ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 40051ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 40061ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 40071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 40081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 40091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 40101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 40111ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 40121ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 40131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 40141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 40151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 40161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 40171ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 40181ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 40191ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 40201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 40211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 40221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 40231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 40241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 4025326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 402650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 402750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 402850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 4029326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 4030326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 4031326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4032326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4033326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 4034326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4035326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 403650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 403750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 403850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 403950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 404050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 404150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 404250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 404350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 4044326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 4045326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 4046326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 4047326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 4048326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 4049326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4050326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 4051326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 4052326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 4053326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 4054326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 405589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 405689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 405789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 405889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 405989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 406089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 406189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 406289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 406389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 4064f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 4065f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 406689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 406789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 406889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 406989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 407089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 407189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 407289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 4073f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4074f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 4075f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 4076f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 4077f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 4078f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 4079f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 4080f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 408189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 408289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4083f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4084f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 4085f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 408647a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 408747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 408847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 4089194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 4090194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 409147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 409247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 409347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 409447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 409547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 409647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 409747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 409847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 409947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 410047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 410147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 410247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 410347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 410447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 410547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 410647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 4107f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 4108f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 410947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 4110f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 4111f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 4112f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 411347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 4114194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 4115194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 4116194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 4117194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4118194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 4119194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 4120194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 41214ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 4122194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 4123194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 4124194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 412547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 412647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 412747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 4128fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 4129fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 4130fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4131fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 4132fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 4133fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 413419cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 4135193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 4136193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 413719cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 4138e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 4139189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 4140189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 4141a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 4142a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 4143a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 4144a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4145189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 4146a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 4147189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4148f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 4149f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 4150f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 4151f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 4152a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 4153a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 4154a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 4155a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4156a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 4157fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 4158fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 4159e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 4160e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 4161e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 4162e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 4163e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 4164e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 4165e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 4166e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 416716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4168e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 4169e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 4170e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 417116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4172e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 4173e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 4174e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 417547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 4176b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 417788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 417888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 4179f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 4180f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 418147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 418247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 4183194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 4184194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 4185194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 4186194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 4187fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 418816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4189c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 4190146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 4191fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 4192fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 41931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 4194ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 4195ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 4196ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 41971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 4198515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 41991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 4200515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 42011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 4202515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 42031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 4204515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 42051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 4206ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4207ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4208ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 42091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 4210ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 42111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 4212ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 4213ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 4214ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 4215ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 4216ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4217ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4218aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 4219ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4220ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 4221ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 422216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4223ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 4224ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 4225ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 4226b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4227ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4228ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4229ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4230b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4231ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 4232ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4233ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 42341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 4235515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 42361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 4237515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4238515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4239b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4240515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4241515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 4242515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 4243515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4244515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4245515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4246515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 42471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 4248515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 42491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 42506469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 42516469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 42526469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 42536469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 42546469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 42556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 42566469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 42576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 42586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 42596469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 42606469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 42616469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 42626469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 42636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4264515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4265515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4266b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4267515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 42686469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 42696469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 42706469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 42716469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 42726469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4273642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 4274642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 4275642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 4276515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4277515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4278515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 42791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 4280515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 42811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 428218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4283515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 4284515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 428538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 428658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 4287b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 428858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 42899e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 4290515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4291515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 4292515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4293515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 429418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4295b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4296515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4297515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 4298515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4299515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4300515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4301515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 43021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 4303515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 43041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 430518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4306515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 4307515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 430818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 430958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 4310b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 431158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 4312b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4313515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4314515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 4315515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4316515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 431718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4318b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4319515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 432032869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 432198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 4322ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 432398447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 432432869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 432598447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 4326ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 432798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 4328eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 43292a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 4330515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4331515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4332515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 433390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 433490b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 43359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 4336ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 433794b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 433894b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 433990b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 4340ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 43413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 43420692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 43430692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 43443483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 4345