ARMAsmParser.cpp revision f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// The LLVM Compiler Infrastructure 4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source 6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details. 7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===// 9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h" 2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h" 23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 2589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach#include "llvm/Support/MathExtras.h" 26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 28fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h" 3075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h" 32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 34345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 35c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4394b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 44ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach struct { 48f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes Cond; // Condition for IT block. 49f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Mask:4; // Condition mask for instructions. 50f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Starting at first 1 (from lsb). 51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '1' condition as indicated in IT. 52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // '0' inverse of condition (else). 53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Count of instructions in IT block is 54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // 4 - trailingzeroes(mask) 55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool FirstCond; // Explicit flag for when we're parsing the 57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // First instruction in the IT block. It's 58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // implied in the mask, so needs special 59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // handling. 60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned CurPosition; // Current position in parsing of IT 62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // block. In range [0,3]. Initialized 63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // according to count of instructions in block. 64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // ~0U if no active IT block. 65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } ITState; 66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach bool inITBlock() { return ITState.CurPosition != ~0U;} 67a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach void forwardITPosition() { 68a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (!inITBlock()) return; 69a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Move to the next instruction in the IT block, if there is one. If not, 70a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // mark the block as done. 71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach unsigned TZ = CountTrailingZeros_32(ITState.Mask); 72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (++ITState.CurPosition == 5 - TZ) 73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach ITState.CurPosition = ~0U; // Done with the IT block after this. 74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 75f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 76f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 77ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 78ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 79ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 850d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 97515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 9989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool &CarrySetting, unsigned &ProcessorIMod, 10089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask); 1011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 102fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 10316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 104ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 105ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 106ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 107ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 108ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 109ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 110ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 11147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 11247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 11347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 114194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 115194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 116194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 117acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool hasV7Ops() const { 118acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::HasV7Ops; 119acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 12032869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 121ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 122ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 12332869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 124acad68da50581de905a994ed3c6b9c197bcea687James Molloy bool isMClass() const { 125acad68da50581de905a994ed3c6b9c197bcea687James Molloy return STI.getFeatureBits() & ARM::FeatureMClass; 126acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 127ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1310692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1320692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 13689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 13743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 138f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 13943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 140f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 14143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1428bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1448bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 14543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1468bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 147f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 148f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 149f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 150f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 155c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 156580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 158293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 160251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 1619d39036f62674606565217a10db28171b9594bc7Jim Grosbach OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 162ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 163ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 164a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 165a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 166a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 167a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 168eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 169eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 170ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 171ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 173ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1749ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 1759ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &); 176548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 177548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 179ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1807b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1817b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 19314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 194623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 195623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 19688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 19788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 198189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 199189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 200189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 201f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach void processInstruction(MCInst &Inst, 202f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 203d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 204d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 205189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 206ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 20747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 208194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 209f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Match_RequiresNotITBlock, 210194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 211194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 21247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 21347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 214ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 21594b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 216ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 21732869205052430f45d598fba25ab878d8b29da2dEvan Cheng 218ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 219ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 220f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 221f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Not in an ITBlock to start with. 222f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = ~0U; 223ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 224ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 2261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 2271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 228189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 2291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 2301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 23147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 23247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 2331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 2341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 236ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 23716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 23816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 2403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 243146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 24521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CondCode, 24621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CCOut, 24721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ITCondMask, 24821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocNum, 24921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_CoprocReg, 25021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Immediate, 25121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_FPImmediate, 25221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MemBarrierOpt, 25321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Memory, 25421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_PostIndexRegister, 25521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_MSRMask, 25621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ProcIFlags, 257460a90540b045c102012da2492999557e6840526Jim Grosbach k_VectorIndex, 25821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Register, 25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RegisterList, 26021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_DPRRegisterList, 26121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_SPRRegisterList, 26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedRegister, 26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShiftedImmediate, 26421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_ShifterImmediate, 26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_RotateImmediate, 26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_BitfieldDescriptor, 26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach k_Token 268a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 269a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 27124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2758462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2768462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 279fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 280fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 281fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 282fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 28389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 28489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 28589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 28689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 28789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 28889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 28989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 29089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 291a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 292a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 293a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 294a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 298584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 299a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3078155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 308460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned Val; 309460a90540b045c102012da2492999557e6840526Jim Grosbach } VectorIndex; 310460a90540b045c102012da2492999557e6840526Jim Grosbach 311460a90540b045c102012da2492999557e6840526Jim Grosbach struct { 312cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 313cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 31416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3159d39036f62674606565217a10db28171b9594bc7Jim Grosbach struct { 3169d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned Val; // encoded 8-bit representation 3179d39036f62674606565217a10db28171b9594bc7Jim Grosbach } FPImm; 3189d39036f62674606565217a10db28171b9594bc7Jim Grosbach 3196a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 3227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 3237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 3247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 3257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 3267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 3270d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm; // shift for OffsetReg. 3287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 3300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 3310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 3327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 333f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 334f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 335f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 3367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 3377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 339580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 340e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 341580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 342e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 343e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 344e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 345e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 346e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 347af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 34892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 34992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 35092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 35192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 352af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 3537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 3547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 356293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 357293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 358293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 359293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 360a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 36116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 362146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 363146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 364762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 365762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 366762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 367762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 368762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 36921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 3708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 37221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: 37389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 37489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 37521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 3768462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 377762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 37821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 37921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 380762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 381762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 38221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 38321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 38421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: 38524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 3868d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 38721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 38821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 389fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 390fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 39121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 392762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 393762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 39421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 3959d39036f62674606565217a10db28171b9594bc7Jim Grosbach FPImm = o.FPImm; 3969d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 39721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 398706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 399706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 40021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 401762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 402762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 40321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 4047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 4057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 407584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 408584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 40921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: 410a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 4110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 41221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 413580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 4140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 41521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 416af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 417e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 41821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 419af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 42092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 42121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 4227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 4237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 42421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 425293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 426293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 427460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 428460a90540b045c102012da2492999557e6840526Jim Grosbach VectorIndex = o.VectorIndex; 429460a90540b045c102012da2492999557e6840526Jim Grosbach break; 430762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 431762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 43216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 433762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 434762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 435762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 436762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 437a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4388462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_CondCode && "Invalid access!"); 4408462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 4418462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4428462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 443fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 44421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 445fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 446fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 447fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 448a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 44921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Token && "Invalid access!"); 450a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 451a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 453a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 4557729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 456a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 457a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4585fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 45921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 46021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind == k_SPRRegisterList) && "Invalid access!"); 46124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 4628d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 4638d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 464cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 46521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_Immediate && "Invalid access!"); 466cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 467cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 468cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 4699d39036f62674606565217a10db28171b9594bc7Jim Grosbach unsigned getFPImm() const { 47021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_FPImmediate && "Invalid access!"); 4719d39036f62674606565217a10db28171b9594bc7Jim Grosbach return FPImm.Val; 4729d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 4739d39036f62674606565217a10db28171b9594bc7Jim Grosbach 474460a90540b045c102012da2492999557e6840526Jim Grosbach unsigned getVectorIndex() const { 475460a90540b045c102012da2492999557e6840526Jim Grosbach assert(Kind == k_VectorIndex && "Invalid access!"); 476460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val; 477460a90540b045c102012da2492999557e6840526Jim Grosbach } 478460a90540b045c102012da2492999557e6840526Jim Grosbach 479706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 48021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MemBarrierOpt && "Invalid access!"); 481706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 482706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 483706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 484a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 48521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_ProcIFlags && "Invalid access!"); 486a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 487a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 488a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 489584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 49021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach assert(Kind == k_MSRMask && "Invalid access!"); 491584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 492584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 493584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 49421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocNum() const { return Kind == k_CoprocNum; } 49521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCoprocReg() const { return Kind == k_CoprocReg; } 49621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCondCode() const { return Kind == k_CondCode; } 49721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isCCOut() const { return Kind == k_CCOut; } 49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITMask() const { return Kind == k_ITCondMask; } 49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isITCondCode() const { return Kind == k_CondCode; } 50021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isImm() const { return Kind == k_Immediate; } 50121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isFPImm() const { return Kind == k_FPImmediate; } 502a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isImm8s4() const { 50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 504a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 505a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 506a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!CE) return false; 507a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Value = CE->getValue(); 508a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 509a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 51072f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 51121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 51272f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 51372f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 51472f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 51572f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 51672f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 51772f39f8436848885176943b0ba985a7171145423Jim Grosbach } 51872f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 51921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 52072f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 52172f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 52272f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 52372f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 52472f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 52572f39f8436848885176943b0ba985a7171145423Jim Grosbach } 5266b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 52721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5286b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5296b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5306b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 5336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 53483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 53683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 53783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 53883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 53983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 54083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 54183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 54283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 54483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 54583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 54683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 54783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 54883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 54983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 5507c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 55121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5527c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 5537c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5547c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 5557c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 5567c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 5577c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 558f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 55921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 560f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 561f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 562f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 563f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 564f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 565f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 5664a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 56721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 5684a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 5694a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5704a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 5714a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 5724a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 5734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 574fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 57521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 576fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 577fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 578fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 579fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 580fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 581fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 582ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 58321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 584ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 585ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 586ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 587ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 588ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 589ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 590ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 591ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 592ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 59321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 594ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 595ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 596ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 597ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 598ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 599ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 60070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 60121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 60270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 60370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 60470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 60570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 60670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 60770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 608f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 60921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 610f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 611f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 612f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 613f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 614f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 615f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 616f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 61721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 618f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 619f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 620f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 621f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 622f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 623f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 6246bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 62521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6266bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 6276bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6286bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 6296bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 6306bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 6316bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 6326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 63321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 6346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 6356b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6366b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 6376b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 6386b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 6396b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 640c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 64121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 642c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 643c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 644c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 645c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 646c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 647c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 64821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isReg() const { return Kind == k_Register; } 64921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegList() const { return Kind == k_RegisterList; } 65021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 65121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 65221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isToken() const { return Kind == k_Token; } 65321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 65421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMemory() const { return Kind == k_Memory; } 65521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isShifterImm() const { return Kind == k_ShifterImmediate; } 65621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 65721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 65821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isRotImm() const { return Kind == k_RotateImmediate; } 65921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 66021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 661f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 66221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 663f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 6647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemNoOffset() const { 665f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 666ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 6677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 6687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 669ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 6707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 671f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 672ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 6737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 6747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return true; 6757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 6767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 6797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 680039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 68121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 682039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 683039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 684039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 685039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 686039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 687039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 688039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 6892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 690f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 6912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 6922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 6932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.ShiftType != ARM_AM::no_shift) return false; 6942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 6952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.OffsetRegNum) return true; 6962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 6972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetImm) return true; 6982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 7002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 70221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate && Kind != k_PostIndexRegister) 7032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 70421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) 7052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 7062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 7072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 7092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 710251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 711251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 7122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 7137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 714f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory()) 715ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 7167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 7177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return false; 7187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 7197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 7207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 7210da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 7220da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson Val == INT32_MIN; 7237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 7247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBB() const { 725f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || !Mem.OffsetRegNum || Mem.isNegative || 7267f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Mem.ShiftType != ARM_AM::no_shift) 7277f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7287f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7297f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7307f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach bool isMemTBH() const { 731f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || !Mem.OffsetRegNum || Mem.isNegative || 7327f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm != 1) 7337f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return false; 7347f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach return true; 7357f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 7367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 737f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || !Mem.OffsetRegNum) 738ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 739ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 740ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 741ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach bool isT2MemRegOffset() const { 742f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || !Mem.OffsetRegNum || Mem.isNegative) 743ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 744ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach // Only lsl #{0, 1, 2, 3} allowed. 745ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach if (Mem.ShiftType == ARM_AM::no_shift) 746ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 747ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach if (Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm > 3) 748ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return false; 749ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach return true; 750ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 7517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 7527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 7537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 754f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || !Mem.OffsetRegNum || Mem.isNegative || 7557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftType != ARM_AM::no_shift) 75687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 75760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return isARMLowRegister(Mem.BaseRegNum) && 75860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum)); 75960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 76060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 761f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0 || 76260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 76360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 76460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 76560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (!Mem.OffsetImm) return true; 76660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 767ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 768ecd858968384be029574d845eb098d357049e02eJim Grosbach } 76938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 770f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0 || 77138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 77238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 77338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 77438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (!Mem.OffsetImm) return true; 77538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 77638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 77738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 77848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 779f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0 || 78048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 78148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 78248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 78348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (!Mem.OffsetImm) return true; 78448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 78548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 78648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 787ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 788f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP) 789ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 790ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 791ecd858968384be029574d845eb098d357049e02eJim Grosbach if (!Mem.OffsetImm) return true; 792ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 793ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 794505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 795a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach bool isMemImm8s4Offset() const { 796f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0) 797a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return false; 798a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Immediate offset a multiple of 4 in range [-1020, 1020]. 799a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach if (!Mem.OffsetImm) return true; 800a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 801a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 802a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 803b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach bool isMemImm0_1020s4Offset() const { 804f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0) 805b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return false; 806b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // Immediate offset a multiple of 4 in range [0, 1020]. 807b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach if (!Mem.OffsetImm) return true; 808b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 809b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 810b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 8117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 812f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0) 813f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 8147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 8157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 8167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 8174d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson return (Val == INT32_MIN) || (Val > -256 && Val < 256); 818f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 819f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach bool isMemPosImm8Offset() const { 820f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0) 821f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return false; 822f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach // Immediate offset in range [0, 255]. 823f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach if (!Mem.OffsetImm) return true; 824f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 825f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach return Val >= 0 && Val < 256; 826f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 827a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemNegImm8Offset() const { 828f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0) 829a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 830a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [-255, -1]. 831a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach if (!Mem.OffsetImm) return true; 832a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 833a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return Val > -256 && Val < 0; 834a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 835a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach bool isMemUImm12Offset() const { 836a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 837a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 838a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // and we reject it. 83921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 840a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return true; 841a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 842f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0) 843a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return false; 844a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Immediate offset in range [0, 4095]. 845a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach if (!Mem.OffsetImm) return true; 846a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 847a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return (Val >= 0 && Val < 4096); 848a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 8497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 85009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 85109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 85209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 85321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 85409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 85509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 856f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach if (!isMemory() || Mem.OffsetRegNum != 0) 857ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 8597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 8610da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 8627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 8637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 86421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind != k_Immediate) 8657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 8667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 867ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 8687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 86963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 870ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 8717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 87221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isMSRMask() const { return Kind == k_MSRMask; } 87321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach bool isProcIFlags() const { return Kind == k_ProcIFlags; } 8743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 875460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex8() const { 876460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 877460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 8; 878460a90540b045c102012da2492999557e6840526Jim Grosbach } 879460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex16() const { 880460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 881460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 4; 882460a90540b045c102012da2492999557e6840526Jim Grosbach } 883460a90540b045c102012da2492999557e6840526Jim Grosbach bool isVectorIndex32() const { 884460a90540b045c102012da2492999557e6840526Jim Grosbach if (Kind != k_VectorIndex) return false; 885460a90540b045c102012da2492999557e6840526Jim Grosbach return VectorIndex.Val < 2; 886460a90540b045c102012da2492999557e6840526Jim Grosbach } 887460a90540b045c102012da2492999557e6840526Jim Grosbach 888460a90540b045c102012da2492999557e6840526Jim Grosbach 889460a90540b045c102012da2492999557e6840526Jim Grosbach 8903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 89114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 89214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 89314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 89414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 8953483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 8963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 8973483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 8983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 8993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 901345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 9028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 90304f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 90404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 9058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 9068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 907fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 908fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 909fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 910fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 911fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 91289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 91389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 91489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 91589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 91689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 91789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 91889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 91989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 92089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 92189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 922fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 923fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 924fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 925fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 926fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 927d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 928d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 929d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 930d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 931d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 932a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 933a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 934a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 935a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 936a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 937af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 938e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 939af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 940af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 941af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 942e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 943af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 944e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 945e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 946af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 947152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 948af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 949af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 95092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 951af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 95292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 95392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 954580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 9550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 956580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 957580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 9580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 9590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 96087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 9617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 9625fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 9635fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 9647729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 9657729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 96687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 96787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 9680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 9690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 9700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 9710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 9730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 9740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 9750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 9777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 9797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 9807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 9817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 982293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 983293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 984293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 985293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 986293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 987293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 988293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 989293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 990293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 991293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 992293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 9933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 9946b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 9966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 9976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 9989d39036f62674606565217a10db28171b9594bc7Jim Grosbach void addFPImmOperands(MCInst &Inst, unsigned N) const { 9999d39036f62674606565217a10db28171b9594bc7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10009d39036f62674606565217a10db28171b9594bc7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getFPImm())); 10019d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 10029d39036f62674606565217a10db28171b9594bc7Jim Grosbach 1003a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1004a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1005a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // FIXME: We really want to scale the value here, but the LDRD/STRD 1006a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // instruction don't encode operands that way yet. 1007a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1008a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1009a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1010a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 101172f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 101272f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 101372f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 101472f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 101572f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 101672f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 101772f39f8436848885176943b0ba985a7171145423Jim Grosbach } 101872f39f8436848885176943b0ba985a7171145423Jim Grosbach 101972f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 102072f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 102172f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 102272f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 102372f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 102472f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 102572f39f8436848885176943b0ba985a7171145423Jim Grosbach } 102672f39f8436848885176943b0ba985a7171145423Jim Grosbach 10276b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 10286b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10296b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 10306b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 10316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 103283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 103383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 103483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 103583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 103683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 103783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 10387c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10397c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 10407c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 10417c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 10427c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 104383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 104483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 104583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 104683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 1047f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1048f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1049f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 1050f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 1051f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1052f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1053f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 1054f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 10554a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 10564a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 10574a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 10584a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 10594a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10604a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 10614a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 10624a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 1063fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 1064fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1065fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 1066fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 1067fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 1068ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 1069ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1070ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 1071ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 1072ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 1073ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 1074ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 1075ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 107670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 107770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 107870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 107970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 108070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 108170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 108270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 108370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 108470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1085ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 1086ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 1087f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 1088f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1089f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 1090f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1091f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1092f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1093f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1094f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 1095f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 1096f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1097f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1098f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1099f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1100f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 11016bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 11026bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 11036bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 11046bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 11056bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 11066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 11073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 11083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 11093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 111016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1111c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 1112c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1113c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 1114c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1115c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1116706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1117706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1118706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1119706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1120706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 11217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 11227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1124505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 1125505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 11267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 11277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 11287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 11297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetRegNum) { 11307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 11317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 11327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 11337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 11347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 11357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 11367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 11377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 11387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 1139dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 1140ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 11417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 11427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 11437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1144ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 1145ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1146039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1147039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1148039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1149039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 1150039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 1151039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1152039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 1153039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 1154039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 1155039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1156039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 1157039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1158039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 1159039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 11602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 11612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 11622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 11632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetRegNum) { 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; 11682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 11692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 11702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 11712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 11722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 11732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 11742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 11752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 11762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 11772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 11782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 11792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 11802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 118121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_PostIndexRegister) { 11822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 11832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 11842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 11852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1186251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 11872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 11882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 11892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 11902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 11912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 11922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 11932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 11942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 11952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1196251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 11972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 11982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 11992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 12002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 12017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 12027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 12037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 12047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 12057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 12067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 12077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 12087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 12097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 12107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 12137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 1214a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1215a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1216a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 1217a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1218a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1219a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach } 1220a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 1221b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1222b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1223b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach // The lower two bits are always zero and as such are not encoded. 1224b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 1225b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1226b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1227b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach } 1228b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach 12297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 12307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 12317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 12327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1234ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1235ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1236f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1237f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1238f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach } 1239f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach 1240a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1241f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach addMemImm8OffsetOperands(Inst, N); 1242a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1243a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1244a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1245a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1246a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // If this is an immediate, it's a label reference. 124721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 1248a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach addExpr(Inst, getImm()); 1249a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 1250a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach return; 1251a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1252a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 1253a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach // Otherwise, it's a normal memory reg+offset. 1254a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 1255a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1256a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1257a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach } 1258a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach 12597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 12607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 126109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 126221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach if (Kind == k_Immediate) { 126309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 126409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 126509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 126609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 126709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 126809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 12697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 12707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 127392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 12747f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBBOperands(MCInst &Inst, unsigned N) const { 12757f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 12767f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12777f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 12787f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 12797f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 12807f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach void addMemTBHOperands(MCInst &Inst, unsigned N) const { 12817f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach assert(N == 2 && "Invalid number of operands!"); 12827f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12837f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 12847f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach } 12857f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach 12867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 12877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 12887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 12890d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 12907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 12917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 12927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 12937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1294d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 1295ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1296ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach assert(N == 3 && "Invalid number of operands!"); 1297ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1298ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 1299ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach Inst.addOperand(MCOperand::CreateImm(Mem.ShiftImm)); 1300ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach } 1301ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach 13027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 13037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 13047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 13057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 130614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 13073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 130860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 130960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 131060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 131160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 131260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 131348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 131448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 131538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 131638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 131738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0; 131838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 131938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 132038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 132138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 132248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 132348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 132448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0; 132548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 132648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 132760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 132860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1329ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1330ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1331ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 1332ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1333ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1334ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1335ecd858968384be029574d845eb098d357049e02eJim Grosbach 13367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 13377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 13387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 13397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 13407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 13417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 134263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 13437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 13447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1345f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1346ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 13477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 13487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 13497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1350f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1351f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1352f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1353f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1354f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1355f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1356f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1357f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1358f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1359f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1360f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1361f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1362ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1363ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1364584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1365584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1366584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1367584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1368584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1369a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1370a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1371a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1372a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1373a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1374460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1375460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1376460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1377460a90540b045c102012da2492999557e6840526Jim Grosbach } 1378460a90540b045c102012da2492999557e6840526Jim Grosbach 1379460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1380460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1381460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1382460a90540b045c102012da2492999557e6840526Jim Grosbach } 1383460a90540b045c102012da2492999557e6840526Jim Grosbach 1384460a90540b045c102012da2492999557e6840526Jim Grosbach void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1385460a90540b045c102012da2492999557e6840526Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 1386460a90540b045c102012da2492999557e6840526Jim Grosbach Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1387460a90540b045c102012da2492999557e6840526Jim Grosbach } 1388460a90540b045c102012da2492999557e6840526Jim Grosbach 1389b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1390b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 139189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 139221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ITCondMask); 139389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 139489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 139589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 139689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 139789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 139889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 13993a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 140021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CondCode); 1401345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1402345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1403345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 14043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1405345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1406345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1407fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 140821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocNum); 1409fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1410fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1411fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1412fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1413fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1414fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1415fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 141621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CoprocReg); 1417fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1418fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1419fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1420fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1421fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1422fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1423d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 142421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_CCOut); 1425d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1426d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1427d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1428d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1429d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1430d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 14313a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 143221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Token); 1433762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1434762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1435762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1436762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 14373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1438a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1439a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 144121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Register); 1442762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1443762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1444762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 14453a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1446a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1447a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1448e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1449e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1450e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1451e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1452e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 145321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1454af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1455af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1456af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1457af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1458e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1459e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1460e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1461e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1462e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 146392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 146492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 146592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 146692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 146721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1468af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1469af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1470af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 147192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 147292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 147392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 147492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 147592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1476580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 14770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 147821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1479580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1480580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 14810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 14820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 14830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 14840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 14850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 148721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_RotateImmediate); 14887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 14897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 14907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 14917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 14927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 14937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1494293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1495293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 149621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 1497293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1498293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1499293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1500293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1501293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1502293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1503293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 15047729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 15055fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1506cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 150721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach KindTy Kind = k_RegisterList; 15080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1509d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 151021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_DPRRegisterList; 1511d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1512275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 151321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach Kind = k_SPRRegisterList; 15140f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 15150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 15165fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 15177729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 151824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1519cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1520cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1521cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 15228d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 15238d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 15248d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 1525460a90540b045c102012da2492999557e6840526Jim Grosbach static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 1526460a90540b045c102012da2492999557e6840526Jim Grosbach MCContext &Ctx) { 1527460a90540b045c102012da2492999557e6840526Jim Grosbach ARMOperand *Op = new ARMOperand(k_VectorIndex); 1528460a90540b045c102012da2492999557e6840526Jim Grosbach Op->VectorIndex.Val = Idx; 1529460a90540b045c102012da2492999557e6840526Jim Grosbach Op->StartLoc = S; 1530460a90540b045c102012da2492999557e6840526Jim Grosbach Op->EndLoc = E; 1531460a90540b045c102012da2492999557e6840526Jim Grosbach return Op; 1532460a90540b045c102012da2492999557e6840526Jim Grosbach } 1533460a90540b045c102012da2492999557e6840526Jim Grosbach 15343a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 153521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Immediate); 1536762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1537762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1538762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 15393a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1540cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1541cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 15429d39036f62674606565217a10db28171b9594bc7Jim Grosbach static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 154321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_FPImmediate); 15449d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->FPImm.Val = Val; 15459d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->StartLoc = S; 15469d39036f62674606565217a10db28171b9594bc7Jim Grosbach Op->EndLoc = S; 15479d39036f62674606565217a10db28171b9594bc7Jim Grosbach return Op; 15489d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 15499d39036f62674606565217a10db28171b9594bc7Jim Grosbach 15507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 15517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 15527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 15537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 15540d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 15557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 15563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 155721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_Memory); 1558762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 15597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetImm = OffsetImm; 15607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetRegNum = OffsetRegNum; 1561762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 15620d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Op->Mem.ShiftImm = ShiftImm; 15637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.isNegative = isNegative; 15647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 15657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 15667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 15677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 156816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1569f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1570f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1571f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 15727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 157321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 15747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1575f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1576f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1577f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1578762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1579762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 15803a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1581a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1582706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1583706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 158421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 1585706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1586706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1587706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1588706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1589706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1590a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1591a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 159221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_ProcIFlags); 1593a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1594a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1595a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1596a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1597a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 160021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach ARMOperand *Op = new ARMOperand(k_MSRMask); 1601584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1603584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1604584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1605584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1606a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1608a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1609a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1610b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1611fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 161221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_FPImmediate: 16139d39036f62674606565217a10db28171b9594bc7Jim Grosbach OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 16149d39036f62674606565217a10db28171b9594bc7Jim Grosbach << ") >"; 16159d39036f62674606565217a10db28171b9594bc7Jim Grosbach break; 161621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CondCode: 16176a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1618fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 161921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CCOut: 1620d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1621d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 162221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ITCondMask: { 162389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)", 162489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)", 162589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(tee)", "(eee)" }; 162689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 162789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 162889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 162989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 163021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocNum: 1631fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1632fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 163321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_CoprocReg: 1634fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1635fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 163621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MSRMask: 1637584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1638584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 163921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Immediate: 1640fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1641fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 164221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_MemBarrierOpt: 1643706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1644706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 164521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Memory: 16466ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 16477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << " base:" << Mem.BaseRegNum; 16486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1649fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 165021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_PostIndexRegister: 1651f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1652f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1653f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1654f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1655f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1656f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 16577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 165821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ProcIFlags: { 1659a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1660a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1661a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1662a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1663a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1664a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1665a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1666a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 166721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Register: 166850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1669fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 167021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShifterImmediate: 1671580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1672580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1673e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 167421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedRegister: 167592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1676af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1677af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1678af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1679af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1680e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 16810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 168221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_ShiftedImmediate: 168392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1684af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1685af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1686af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 168792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 168892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 168921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RotateImmediate: 16907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 16917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 169221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_BitfieldDescriptor: 1693293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1694293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1695293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 169621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_RegisterList: 169721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_DPRRegisterList: 169821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_SPRRegisterList: { 16998d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 17008d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 17015fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 17025fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 17037729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 17047729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 17057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 17068d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 17078d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 17088d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 17098d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 17108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 171121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach case k_Token: 1712fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1713fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1714460a90540b045c102012da2492999557e6840526Jim Grosbach case k_VectorIndex: 1715460a90540b045c102012da2492999557e6840526Jim Grosbach OS << "<vectorindex " << getVectorIndex() << ">"; 1716460a90540b045c102012da2492999557e6840526Jim Grosbach break; 1717fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1718fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 17193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 17203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 17213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 17223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 17233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 17243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 17253483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 17263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 172769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 172869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 17291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1730bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1731bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1732bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1733bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 17349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1735e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1736e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 17373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 17381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 173918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 17407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1741d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1742a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1743a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 17440c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 17450c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 17460c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 17470c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 17480c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 17490c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 17500c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 17510c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 17520c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 17530c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 17540c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 17550c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 175669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1757b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1758460a90540b045c102012da2492999557e6840526Jim Grosbach 1759460a90540b045c102012da2492999557e6840526Jim Grosbach#if 0 1760460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 1761460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 1762460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 1763460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 1764460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 1765460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 1766460a90540b045c102012da2492999557e6840526Jim Grosbach 1767460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 1768460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc ExprLoc = Parser.getTok().getLoc(); 1769460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 1770460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1771460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 1772460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 1773460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 1774460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1775460a90540b045c102012da2492999557e6840526Jim Grosbach } 1776460a90540b045c102012da2492999557e6840526Jim Grosbach 1777460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 1778460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 1779460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 1780460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1781460a90540b045c102012da2492999557e6840526Jim Grosbach } 1782460a90540b045c102012da2492999557e6840526Jim Grosbach 1783460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 1784460a90540b045c102012da2492999557e6840526Jim Grosbach 1785460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 1786460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 1787460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 1788460a90540b045c102012da2492999557e6840526Jim Grosbach } 1789460a90540b045c102012da2492999557e6840526Jim Grosbach#endif 1790460a90540b045c102012da2492999557e6840526Jim Grosbach 1791e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1792e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1793d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 179419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 179519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 179619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 179719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 179819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 17990d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 18000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 18010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 18020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 18030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 18040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 18050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 18060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 18070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 18080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 18090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 18100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 18110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 18120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 18130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 18140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 18150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 181619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 18170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1818e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1819e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1820e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1821e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1822e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1823eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1824e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1825e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1826e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1827e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1828e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1829e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1830e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1831e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1832e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1833e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1834e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1835e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1836e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1837e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1838e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1839e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 184019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 184119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 184219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 184319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1844e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1845e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 184619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 184719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 184819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 184919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1850e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1851e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1852e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1853e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1854e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1855e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1856e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 185719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 185819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1859e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1860e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 18611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1862e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 186319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 186419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 186519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 186619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 186719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 186819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1869e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 187019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 187119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1872e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1873e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 187492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 187592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1876af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 18770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 187892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 187992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 188092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 18810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 188219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 18830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 18840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 18850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 188650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 188750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 188850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1889e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1890e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1891e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 189250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 18931355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1894e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 18951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1896e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 189750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1898d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 189950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1900a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1901e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1902e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 190350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 190450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1905e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 1906460a90540b045c102012da2492999557e6840526Jim Grosbach return false; 1907460a90540b045c102012da2492999557e6840526Jim Grosbach } 1908460a90540b045c102012da2492999557e6840526Jim Grosbach 1909460a90540b045c102012da2492999557e6840526Jim Grosbach // Also check for an index operand. This is only legal for vector registers, 1910460a90540b045c102012da2492999557e6840526Jim Grosbach // but that'll get caught OK in operand matching, so we don't need to 1911460a90540b045c102012da2492999557e6840526Jim Grosbach // explicitly filter everything else out here. 1912460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().is(AsmToken::LBrac)) { 1913460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc SIdx = Parser.getTok().getLoc(); 1914460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat left bracket token. 1915460a90540b045c102012da2492999557e6840526Jim Grosbach 1916460a90540b045c102012da2492999557e6840526Jim Grosbach const MCExpr *ImmVal; 1917460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc ExprLoc = Parser.getTok().getLoc(); 1918460a90540b045c102012da2492999557e6840526Jim Grosbach if (getParser().ParseExpression(ImmVal)) 1919460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1920460a90540b045c102012da2492999557e6840526Jim Grosbach const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 1921460a90540b045c102012da2492999557e6840526Jim Grosbach if (!MCE) { 1922460a90540b045c102012da2492999557e6840526Jim Grosbach TokError("immediate value expected for vector index"); 1923460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1924460a90540b045c102012da2492999557e6840526Jim Grosbach } 1925460a90540b045c102012da2492999557e6840526Jim Grosbach 1926460a90540b045c102012da2492999557e6840526Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 1927460a90540b045c102012da2492999557e6840526Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) { 1928460a90540b045c102012da2492999557e6840526Jim Grosbach Error(E, "']' expected"); 1929460a90540b045c102012da2492999557e6840526Jim Grosbach return MatchOperand_ParseFail; 1930460a90540b045c102012da2492999557e6840526Jim Grosbach } 1931460a90540b045c102012da2492999557e6840526Jim Grosbach 1932460a90540b045c102012da2492999557e6840526Jim Grosbach Parser.Lex(); // Eat right bracket token. 1933460a90540b045c102012da2492999557e6840526Jim Grosbach 1934460a90540b045c102012da2492999557e6840526Jim Grosbach Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 1935460a90540b045c102012da2492999557e6840526Jim Grosbach SIdx, E, 1936460a90540b045c102012da2492999557e6840526Jim Grosbach getContext())); 193799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 193899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 193950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1940a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1941a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1942fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1943fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1944fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1945fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1946e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1947e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1948e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1949e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1950e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1951fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1952e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1953e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1954e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1955e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1956e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1957e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1958e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1959e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1960e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1961e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1962e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1963e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1964e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1965e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1966e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1967e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1968fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1969e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1970e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1971e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1972e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1973e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1974e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1975e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1976e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1977e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1978e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1979e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1980e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1981e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1982e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1983e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1984e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 198589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 198689df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 198789df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 198889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 198989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 199089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 199189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 199289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 199389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 199489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 199589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 199689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 199789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 199889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 199989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 200089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 200189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 200289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 200389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 200489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 200589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 200689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 200789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 200889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 200989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 201089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 201189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 201289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 201389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 201489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 201589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 201689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 201789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 201889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 201989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 202043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2021fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2022fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2023f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 202443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2025e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 2026e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 2027e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2028e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2029fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2030e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 2031f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2032e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2033e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 2034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2035f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2036fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 2037fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 203843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2039fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 2040fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 2041f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 204243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2043fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2044fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2045fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2046fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2047fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2048fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 2049f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2050fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2051fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2052fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2053f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2054e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 2055e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2056d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering 2057d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by 2058d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names. 2059d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) { 2060d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If this is a GPR, we need to do it manually, otherwise we can rely 2061d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // on the sort ordering of the enumeration since the other reg-classes 2062d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // are sane. 2063d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2064d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Reg + 1; 2065d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach switch(Reg) { 2066d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach default: assert(0 && "Invalid GPR number!"); 2067d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2068d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2069d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2070d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2071d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2072d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2073d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2074d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2075d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2076d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach} 2077d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2078d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list. 207950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 20801355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 208118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 2082a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 2083e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 2084d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '{' token. 2085d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc RegLoc = Parser.getTok().getLoc(); 208616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2087d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Check the first register in the list to see what register class 2088d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // this is a list of. 2089d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int Reg = tryParseRegister(); 2090d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 2091d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register expected"); 2092d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2093d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach MCRegisterClass *RC; 2094d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2095d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2096d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2097d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2098d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2099d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2100d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach else 2101d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2102e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 2103d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The reglist instructions have at most 16 registers, so reserve 2104d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // space for that many. 2105d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2106d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Store the first register. 2107d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2108d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2109d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // This starts immediately after the first register token in the list, 2110d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // so we can see either a comma or a minus (range separator) as a legal 2111d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // next token. 2112d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Parser.getTok().is(AsmToken::Comma) || 2113d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.getTok().is(AsmToken::Minus)) { 2114d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 2115d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2116d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc EndLoc = Parser.getTok().getLoc(); 2117d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int EndReg = tryParseRegister(); 2118d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (EndReg == -1) 2119d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "register expected"); 2120d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // If the register is the same as the start reg, there's nothing 2121d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // more to do. 2122d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == EndReg) 2123d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2124d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2125d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(EndReg)) 2126d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "invalid register in register list"); 2127d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Ranges must go from low to high. 2128d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2129d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(EndLoc, "bad range in register list"); 2130d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2131d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // Add all the registers in the range to the register list. 2132d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach while (Reg != EndReg) { 2133d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = getNextRegister(Reg); 2134d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2135d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2136d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach continue; 2137d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2138d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat the comma. 2139d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach RegLoc = Parser.getTok().getLoc(); 2140d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach int OldReg = Reg; 2141d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg = tryParseRegister(); 2142d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Reg == -1) 21432d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach return Error(RegLoc, "register expected"); 2144d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // The register must be in the same register class as the first. 2145d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (!RC->contains(Reg)) 2146d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "invalid register in register list"); 2147d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // List must be monotonically increasing. 2148d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg)) 2149d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "register list not in ascending order"); 2150d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register lists must also be contiguous. 2151d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // It's OK to use the enumeration values directly here rather, as the 2152d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach // VFP register classes have the enum sorted properly. 2153d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2154d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Reg != OldReg + 1) 2155d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(RegLoc, "non-contiguous register range"); 2156d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2157d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach } 2158d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach 2159d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2160d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach if (Parser.getTok().isNot(AsmToken::RCurly)) 2161d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach return Error(E, "'}' expected"); 2162d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach Parser.Lex(); // Eat '}' token. 2163e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 216450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 216550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 2166d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 2167d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 216843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2169f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 217043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2171706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2172706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2173706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2174706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 2175706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2176706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2177706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 2178706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 2179032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 2180706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 2181032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 2182706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 2183706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 2184032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 2185706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 2186032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 2187706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 2188706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 2189706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 2190706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 2192f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 2193706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 2194706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2195706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2196f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 2197706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 2198706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 219943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 220143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2202a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2203a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2205a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 2206a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 22072dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // An iflags string of "none" is interpreted to mean that none of the AIF 22082dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // bits are set. Not a terribly useful instruction, but a valid encoding. 2209a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 22102dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (IFlagsStr != "none") { 22112dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 22122dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 22132dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("a", ARM_PROC::A) 22142dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("i", ARM_PROC::I) 22152dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Case("f", ARM_PROC::F) 22162dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson .Default(~0U); 22172dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 22182dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // If some specific iflag is already set, it means that some letter is 22192dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson // present more than once, this is not acceptable. 22202dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson if (Flag == ~0U || (IFlags & Flag)) 22212dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson return MatchOperand_NoMatch; 22222dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson 22232dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson IFlags |= Flag; 22242dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson } 2225a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2226a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2227a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2228a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2229a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 2230584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 2231584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 223243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2233584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 223443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2235584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 2236584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 2237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2238584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 2239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2240acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (isMClass()) { 2241acad68da50581de905a994ed3c6b9c197bcea687James Molloy // See ARMv6-M 10.1.1 2242acad68da50581de905a994ed3c6b9c197bcea687James Molloy unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2243acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("apsr", 0) 2244acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iapsr", 1) 2245acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("eapsr", 2) 2246acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("xpsr", 3) 2247acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("ipsr", 5) 2248acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("epsr", 6) 2249acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("iepsr", 7) 2250acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("msp", 8) 2251acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("psp", 9) 2252acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("primask", 16) 2253acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri", 17) 2254acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("basepri_max", 18) 2255acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("faultmask", 19) 2256acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Case("control", 20) 2257acad68da50581de905a994ed3c6b9c197bcea687James Molloy .Default(~0U); 2258acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2259acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (FlagsVal == ~0U) 2260acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2261acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2262acad68da50581de905a994ed3c6b9c197bcea687James Molloy if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 2263acad68da50581de905a994ed3c6b9c197bcea687James Molloy // basepri, basepri_max and faultmask only valid for V7m. 2264acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_NoMatch; 2265acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2266acad68da50581de905a994ed3c6b9c197bcea687James Molloy Parser.Lex(); // Eat identifier token. 2267acad68da50581de905a994ed3c6b9c197bcea687James Molloy Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2268acad68da50581de905a994ed3c6b9c197bcea687James Molloy return MatchOperand_Success; 2269acad68da50581de905a994ed3c6b9c197bcea687James Molloy } 2270acad68da50581de905a994ed3c6b9c197bcea687James Molloy 2271584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 2272584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 2273584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 2274b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 2275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 2276584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 2277584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2278584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 2279584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 2280584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2281584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 2282584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2283584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 2284584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 2285b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 2286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 2287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 2288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 22904b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 2291584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 2292584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2293584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 2294bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach FlagsVal = 8; // No flag 22954b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 2296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 229756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 229856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 2299584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 2300584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 2301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 2302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 2303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 2304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 2305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 2306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 2308584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 2309584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 2310584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2311584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 2312584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 2313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 2314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 2315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 2317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 2318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 2319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2321584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 2322584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 2323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 2324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 2325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 2327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 2328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2329f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2330f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 2331f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 2332f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2333f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2334f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2335f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2336f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2337f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 2338f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 2339f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 2340f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 2341f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 2342f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2343f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2344f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 2345f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2346f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 2347f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2348f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2349f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2350f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2351f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 2352f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2353f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 2354f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 2355f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2356f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 2357f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2358f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2359f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2360f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 2361f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 2362f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 2365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 2366f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 2367f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 2368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 2369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 2371f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2372f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 2373f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 2374f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 2375c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2376c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2377c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 2378c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 2379c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2380c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2381c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2382c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2383c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 2384c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 2385c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 2386c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 2387c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 2388c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2389c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 2390c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2391c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 2392c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 2393c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 2394c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 2395c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 2396c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 2397c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 2398c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 2399580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 2400580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 2401580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 2402580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 2403580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 2404580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2405580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2406580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 2407580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 2408580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2409580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2410580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2411580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2412580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 2413580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 2414580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 2415580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 2416580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 2417580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 2418580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 2419580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2420580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2421580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2422580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 2423580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2424580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 2425580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2426580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2427580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2428580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2429580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 2430580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2431580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 2432580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2433580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2434580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 2435580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2437580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2438580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 2439580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 2440580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2441580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2442580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2443580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 2444580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 2445580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2446580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 2447580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 2448580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2449580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 24500afa0094afdfe589f407feb76948f273b414b278Owen Anderson // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 24510afa0094afdfe589f407feb76948f273b414b278Owen Anderson if (isThumb() && Val == 32) { 24520afa0094afdfe589f407feb76948f273b414b278Owen Anderson Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 24530afa0094afdfe589f407feb76948f273b414b278Owen Anderson return MatchOperand_ParseFail; 24540afa0094afdfe589f407feb76948f273b414b278Owen Anderson } 2455580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 2456580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 2457580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2458580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 2459580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 2460580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2461580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2462580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2463580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2464580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 2465580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 2466580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2467580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 2468580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 2469580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 24707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 24717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 24727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 24737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 24747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 24757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 24767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 2477326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) 2478326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 24797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 2480326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") 2481326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach return MatchOperand_NoMatch; 24827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 24837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 24847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 24857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 24867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 24877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 24887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 24897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 24907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 24917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 24927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 24937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 24947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 24957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 24967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 24977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 24987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 24997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 25007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 25017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 25027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 25037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 25047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 25057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 25067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 25077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 25087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 25097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 25107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 25117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 25127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 25137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 25147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 25157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 25167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 25177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2518293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2519293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2520293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2521293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2522293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2523293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2524293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2525293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2526293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2527293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2528293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2529293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2530293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2531293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2532293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2533293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2534293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2535293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2536293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2537293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2538293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2539293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2540293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2541293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2542293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2543293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2544293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2545293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2546293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2547293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2548293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2549293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2550293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2551293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2552293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2553293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2554293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2555293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2556293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2557293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2558293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2559293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2560293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2561293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2562293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2563293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2564293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2565293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2566293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2567293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2568293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2569293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2570293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2571293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2572293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2573293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2574293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2575293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2576293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2577293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2578293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2579293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2580293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2581293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2582293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2583293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 25847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 25857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 25867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2587f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2588f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2589f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 25907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 25917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 25927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 25937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 25947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 25957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 25967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 259716578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 25987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 25997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 26007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 26017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 26027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 26037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 260416578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 26057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 26067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 26077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 26087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 26097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 26107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 26117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 26127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 26137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 26147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 26157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 26167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2617f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2618f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 26190d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 26200d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 26210d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 26220d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 26230d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2624f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2625f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2626f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 26277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 26287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 26297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 26307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2631251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2632251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2633251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2634251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2635251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2636251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2637251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2638251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2639251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2640251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2641251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2642251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2643251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2644251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2645251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2646251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2647251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2648251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2649251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2650251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2651251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2652251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2653251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2654251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2655251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2656251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2657251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2658251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2659251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2660251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2661251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2662251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2663251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2664251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2665251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2666251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2667251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2668251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2669251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2670251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2671251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2672251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2673251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2674251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2675251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2676251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2677251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2678251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2679251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2680251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2681251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2682251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2683251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2684251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2685251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2686251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2687251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2688251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2689251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2690251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2691251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2692251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2693251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2694251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2695251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2696251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 2697251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2698251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2699251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 2700251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2701a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst. 2702a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2703a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2704a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 2705a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 2706a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2707a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 2708a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2709a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2710a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 2711a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 2712a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 2713a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 2714a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 2715a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2716a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 2717a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 2718a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 2719a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst. 2720a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2721a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2722a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser:: 2723a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode, 2724a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2725a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Create a writeback register dummy placeholder. 2726a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 2727a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // Rt, Rt2 2728a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2729a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2730a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // addr 2731a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 2732a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach // pred 2733a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2734a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach return true; 2735a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach} 2736a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach 2737eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 2738eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2739eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2740eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser:: 2741eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 2742eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2743eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2744eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2745eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach // Create a writeback register dummy placeholder. 2746eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2747eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2748eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 2749eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2750eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach return true; 2751eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach} 2752eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach 2753ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 2754ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2755ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2756ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser:: 2757ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 2758ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2759ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach // Create a writeback register dummy placeholder. 2760ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2761ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2762ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 2763ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2764ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach return true; 2765ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach} 2766ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach 27671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2768ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2769ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2770ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 27711355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2772ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2773ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2774ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2775ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2776ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2777ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 27787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2779ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2780ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2781ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2782ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 27839ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 27849ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 27859ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 27869ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 27879ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 27889ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 27899ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 27909ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 27919ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 27929ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 27939ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 27949ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 27959ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 27969ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 27979ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 27989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 27999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 2800548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2801548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2802548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2803548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 2804548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2805548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2806548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 2807548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2808548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2809548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2810548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2811548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 2812548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 2813548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 28141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2815ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2816ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2817ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 28181355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2819ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2820ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2822548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2823548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2824548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 28257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 28267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 28277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 28287b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 28297b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 28307b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 28317b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 28327b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 28337b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28347b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 28357b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 28367b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 28377b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 28387b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 28397b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 28407b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 28417b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 28427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 28437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 28447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 28457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 28467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 28477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2849ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 28507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 28517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 28527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 28537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 28547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 28557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 28567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2857ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2858ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2859ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2860ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 28617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2862ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2863ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2864ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 28657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 28667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2868aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2869ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2870ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 28717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 28727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 28737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 28747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 28757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 28767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 28777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 28787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 2879aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 28807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 28817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 28827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 28837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 28847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 28857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 28867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 28877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 28887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 28897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 28907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 28917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 28927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 28937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 28947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2895ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2896ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2897ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2898ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 28997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2900ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2901ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2902ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 29037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 29047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2905ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2906ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 29077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2908ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 29097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 29107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 29117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 29127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 29137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2914ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2915ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2916ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2917ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 29182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 29192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 29202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 29212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 29222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 29232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 29242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 29252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 29262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 29272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 29282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 29292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 29302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 29312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 29322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 29332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 29342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 29352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 293614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 293714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 293814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 293914605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 294014605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 294114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 294214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 294314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 294414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 294514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 294614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 294714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 294814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 294914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 295014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 295114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 295214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 295314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 2954623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2955623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2956623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2957623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 2958623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2959623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2960623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2961623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 2962623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2963623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2964623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2965623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 2966623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 2967623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 296888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 296988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 297088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 297188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 297288ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 297388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 297488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 297588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 297688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 29777a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 29787a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 29797a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 29807a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 298188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 29827a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 298388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 298488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 298588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 298688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 298788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 29887a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // If we have a three-operand form, use that, else the second source operand 29897a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // is just the destination operand again. 29907a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach if (Operands.size() == 6) 29917a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 29927a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach else 29937a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach Inst.addOperand(Inst.getOperand(0)); 299488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 299588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 299688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 299788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 2998623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2999e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 30009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 300150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 30027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3003762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 300418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3005a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 3006762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3007b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 3008a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 300918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 30101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 30117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 30127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 3013a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30140571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 30150571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 30160571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 30177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 30180571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 30197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 3020762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 3021b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 3022a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 30247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, false, S, E)); 302503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 3026fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3027fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach // operand. It's rather odd, but syntactically valid. 3028fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3029fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3030fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach Parser.Lex(); // Eat the '!'. 3031fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach } 3032fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach 30337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 30347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 303550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 30367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 30377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 303850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 30397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If we have a '#' it's an immediate offset, else assume it's a register 30407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 30417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 30427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 30437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 304450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 30450da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 30467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 30477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 30487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 304905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 30507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 30517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 30527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 30537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 30547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 30557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 30567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 30570da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 30580da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 30590da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 30600da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 30610da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 30627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 30637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 30647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 30657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 30667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 306705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 30687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 30697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 30707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 30717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::no_shift, 0, false, S,E)); 3072a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 30747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 30757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 30767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 30777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 3078762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 30797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 30807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 30819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 3082d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 30837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 30847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 30857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 30867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 30877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 30887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 30897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 30907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 30917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 30929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 30937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 30947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 30957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 30967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 30977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 30987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 30997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 31000d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 31017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 31027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 31030d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 31047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 31059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 310616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 31077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 31087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 31097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 31107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 31117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 31127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 31137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 31140d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach ShiftType, ShiftImm, isNegative, 31157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 31167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 3117f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 3118f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 3119f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 3120f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3121f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 3122f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 31239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 31249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 31259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 31269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 31277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 3128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 3129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 31307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 31317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 31327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 31337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 313418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3136a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 313738e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 3138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 31390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 3140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 31410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 3142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 31430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 3144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 31450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 3146a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 31470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 3148a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 31497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 3150b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 3151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 31527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 31537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 31547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 31557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 31567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 31577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 31587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 31597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 31607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 31619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 31627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 31637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 31647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 31657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 31667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 31677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 31687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 31697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 31707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 31717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 31727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 31737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 31747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 31757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 31767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 31777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 3178a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 3180a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3181a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 31829d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand. 31839d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 31849d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 31859d39036f62674606565217a10db28171b9594bc7Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 31869d39036f62674606565217a10db28171b9594bc7Jim Grosbach 31879d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) 31889d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_NoMatch; 31899d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the '#'. 31909d39036f62674606565217a10db28171b9594bc7Jim Grosbach 31919d39036f62674606565217a10db28171b9594bc7Jim Grosbach // Handle negation, as that still comes through as a separate token. 31929d39036f62674606565217a10db28171b9594bc7Jim Grosbach bool isNegative = false; 31939d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 31949d39036f62674606565217a10db28171b9594bc7Jim Grosbach isNegative = true; 31959d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); 31969d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 31979d39036f62674606565217a10db28171b9594bc7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 31989d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Real)) { 31999d39036f62674606565217a10db28171b9594bc7Jim Grosbach APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 32009d39036f62674606565217a10db28171b9594bc7Jim Grosbach uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 32019d39036f62674606565217a10db28171b9594bc7Jim Grosbach // If we had a '-' in front, toggle the sign bit. 32029d39036f62674606565217a10db28171b9594bc7Jim Grosbach IntVal ^= (uint64_t)isNegative << 63; 32039d39036f62674606565217a10db28171b9594bc7Jim Grosbach int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 32049d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 32059d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val == -1) { 32069d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("floating point value out of range"); 32079d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 32089d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32099d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 32109d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 32119d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32129d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Tok.is(AsmToken::Integer)) { 32139d39036f62674606565217a10db28171b9594bc7Jim Grosbach int64_t Val = Tok.getIntVal(); 32149d39036f62674606565217a10db28171b9594bc7Jim Grosbach Parser.Lex(); // Eat the token. 32159d39036f62674606565217a10db28171b9594bc7Jim Grosbach if (Val > 255 || Val < 0) { 32169d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("encoded floating point value out of range"); 32179d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 32189d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32199d39036f62674606565217a10db28171b9594bc7Jim Grosbach Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 32209d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_Success; 32219d39036f62674606565217a10db28171b9594bc7Jim Grosbach } 32229d39036f62674606565217a10db28171b9594bc7Jim Grosbach 32239d39036f62674606565217a10db28171b9594bc7Jim Grosbach TokError("invalid floating point immediate"); 32249d39036f62674606565217a10db28171b9594bc7Jim Grosbach return MatchOperand_ParseFail; 32259d39036f62674606565217a10db28171b9594bc7Jim Grosbach} 32269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 32279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 32281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3229fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 3230762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 3231fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3232fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 3233fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 3234f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 3235f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 3236fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 3237f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 3238f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 3239f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 3240f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 3241f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 3242fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 3243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 3244146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 3245146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 324650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 324719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 32485cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach // If this is VMRS, check for the apsr_nzcv operand. 32491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 325050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 32510d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 325219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 32530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 325419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 325519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 32565cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 32575cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach S = Parser.getTok().getLoc(); 32585cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Parser.Lex(); 32595cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 32605cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach return false; 32615cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach } 3262e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 3263e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 3264e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 326519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 326667b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 326767b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 3268515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 3269515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 3270515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 3271762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3272515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 327350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 3274762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 327550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 327650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 327750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 3278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 32791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 3280d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 32811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 328263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 3283079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 3284079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 3285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 3286b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 328763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 3288515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 3289515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 329050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 329163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 329263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (!CE) { 329363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson Error(S, "constant expression expected"); 329463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return MatchOperand_ParseFail; 329563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 329663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson int32_t Val = CE->getValue(); 329763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (isNegative && Val == 0) 329863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 3299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 330050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 330150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 330263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 33039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 33049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 33057597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 33067597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 33077597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 33081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 33099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 33109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33117597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 33127597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 33139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 33149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33157597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 33167597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 33179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 33187597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 33199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 33209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 3321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 3323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 33241355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 33257597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 33261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 33277597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 33289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 33308a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 33319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 33329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 33349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 33359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 33369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 33379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 33399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 33407597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 33419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 33427597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 33439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 33449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 33459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 33469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 33479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 33489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 33499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 33509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 33519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 33529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 33539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 33549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 33559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 33569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 3357352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 3358352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 3359352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 3360badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 336189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 33621355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 33635f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 33645f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 336589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 336689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 3367352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 3368352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 3369a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 3370352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3371badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 3372352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 3373352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 33745f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 33755f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 33765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 33775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 33785f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 33795f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 33805f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 33815f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 3382352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3383badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 33843f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 33853f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 3386ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 338771725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 338804d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 33892f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach Mnemonic != "sbcs" && Mnemonic != "rscs") { 33903f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 33913f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 33923f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 33933f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 33943f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 33953f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 33963f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 33973f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 33983f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 33993f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 34003f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 34013f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 34023f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 34033f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 34043f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 34053f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 34063f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 34073f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 34083f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 34093f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 34103f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 34113f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 34123f00e317064560ad11168d22030416d853829f6eJim Grosbach } 341352925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 3414345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3415352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 3416352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 3417352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 341800f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 34195f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 34205f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 34215f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 3422e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 3423e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 3424352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 3425352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 3426352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 3427352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 3428a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 3429a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 3430a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 3431a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 3432a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 3433a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 3434a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 3435a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 3436a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 3437a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 3438a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 3439a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 3440a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3441a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3442a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 344389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 344489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 344589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 344689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 344789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 344889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3449352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 3450352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 34513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 34523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 34533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 34543771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 34553771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 3456fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 34571355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 3458fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 3459eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 3460eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 34613443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach Mnemonic == "add" || Mnemonic == "adc" || 3462eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 3463d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "orr" || Mnemonic == "mvn" || 3464eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 3465d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 34663443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 3467d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "mla" || Mnemonic == "smlal" || 3468d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach Mnemonic == "umlal" || Mnemonic == "umull"))) { 3469eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 3470fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 3471eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 34723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 3473eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 3474eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 3475eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 3476eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 3477ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 3478ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach (Mnemonic == "clrex" && !isThumb()) || 34790780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 34804af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw") && 34814af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 34824af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 34834af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 34841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 34853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 3486fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } else 34873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 3488fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 3489fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach if (isThumb()) { 3490fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 349163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 3492fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 3493fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach } 3494badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 3495badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3496d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 3497d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 349820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // FIXME: This is all horribly hacky. We really need a better way to deal 349920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // with optional operands like this in the matcher table. 3500d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3501d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 3502d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 3503d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 3504d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 3505d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 3506d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 3507d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 3508d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 35098adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 3510d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 3511d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 3512d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3513d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 35143912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 35153912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 35163912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 35173912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 35183912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 35193912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 35203912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 35213912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 352272f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 352320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 352420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // have to check the immediate range here since Thumb2 has a variant 352520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // that can handle a different range and has a cc_out operand. 3526f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (((isThumb() && Mnemonic == "add") || 3527f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach (isThumbTwo() && Mnemonic == "sub")) && 3528f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 352972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 353072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 353172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 353220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 353320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach (static_cast<ARMOperand*>(Operands[5])->isReg() || 353420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 353572f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 3536f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // For Thumb2, add/sub immediate does not have a cc_out operand for the 3537f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // imm0_4095 variant. That's the least-preferred variant when 353820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // selecting via the generic "add" mnemonic, so to know that we 353920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // should remove the cc_out operand, we have to explicitly check that 354020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // it's not one of the other variants. Ugh. 3541f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 3542f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Operands.size() == 6 && 354320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 354420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 354520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 354620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Nest conditions rather than one big 'if' statement for readability. 354720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // 354820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If either register is a high reg, it's either one of the SP 354920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // variants (handled above) or a 32-bit encoding, so we just 355020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // check against T3. 355120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 355220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 355320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 355420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 355520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // If both registers are low, we're in an IT block, and the immediate is 355620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // in range, we should use encoding T1 instead, which has a cc_out. 355720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (inITBlock() && 355864944f48a1164c02c15ca423a53919682a89074cJim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 355920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 356020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 356120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return false; 356220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 356320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // Otherwise, we use encoding T4, which does not have a cc_out 356420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // operand. 356520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach return true; 356620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach } 356720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 356864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // The thumb2 multiply instruction doesn't have a CCOut register, so 356964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 357064944f48a1164c02c15ca423a53919682a89074cJim Grosbach // use the 16-bit encoding or not. 357164944f48a1164c02c15ca423a53919682a89074cJim Grosbach if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 357264944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 357364944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 357464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 357564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->isReg() && 357664944f48a1164c02c15ca423a53919682a89074cJim Grosbach // If the registers aren't low regs, the destination reg isn't the 357764944f48a1164c02c15ca423a53919682a89074cJim Grosbach // same as one of the source regs, or the cc_out operand is zero 357864944f48a1164c02c15ca423a53919682a89074cJim Grosbach // outside of an IT block, we have to use the 32-bit encoding, so 357964944f48a1164c02c15ca423a53919682a89074cJim Grosbach // remove the cc_out operand. 358064944f48a1164c02c15ca423a53919682a89074cJim Grosbach (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 358164944f48a1164c02c15ca423a53919682a89074cJim Grosbach !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 358264944f48a1164c02c15ca423a53919682a89074cJim Grosbach !inITBlock() || 358364944f48a1164c02c15ca423a53919682a89074cJim Grosbach (static_cast<ARMOperand*>(Operands[3])->getReg() != 358464944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[5])->getReg() && 358564944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() != 358664944f48a1164c02c15ca423a53919682a89074cJim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg()))) 358764944f48a1164c02c15ca423a53919682a89074cJim Grosbach return true; 358864944f48a1164c02c15ca423a53919682a89074cJim Grosbach 358964944f48a1164c02c15ca423a53919682a89074cJim Grosbach 359020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach 3591f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 3592f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 3593f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 3594f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 3595f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 3596f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 3597f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 359872f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 359972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 360072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 360172f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 36023912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 3603d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 3604d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 3605d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3606badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 3607badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 3608badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3609badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 3610badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 3611ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 3612badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3613352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 3614352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 3615a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 3616352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 361789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 36181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 361989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 3620badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 36210c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 36220c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 36230c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 36240c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 36250c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 36260c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 3627ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 3628ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 362989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 363089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 363189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 363289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 363389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 363489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 3635f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 3636f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITMask.size() > 3) { 3637f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Parser.EatToEndOfStatement(); 3638f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "too many conditions on IT instruction"); 3639f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 364089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 364189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 364289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 364389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 364489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 3645f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 364689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 364789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 364889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 364989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 365089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 3651f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 365289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 365389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3654ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 3655ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 36569717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 36573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 36583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 36593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 36603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 36613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 36623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 36633771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 36643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 36651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 36663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 366733c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 366833c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 366933c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 367033c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 3671ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 367233c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 367333c16a27370939de39679245c3dff72383c210bdJim Grosbach } 3674c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 3675c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 3676c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 3677c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 3678c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 3679c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 3680c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 368133c16a27370939de39679245c3dff72383c210bdJim Grosbach 36823771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 3683f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (CanAcceptCarrySet) { 3684f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 36853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 3686f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Loc)); 3687f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 36883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 36893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 36903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 3691f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 3692f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CarrySetting); 36933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 3694f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::CondCodes(PredicationCode), Loc)); 3695badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 3696345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3697a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 3698a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 3699a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 3700a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 3701a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 3702a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3703a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3704345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 37055747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 37065747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 37075747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 3708a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 3709a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 37104d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // For now, we're only parsing Thumb1 (for the most part), so 37114d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // just ignore ".n" qualifiers. We'll use them to restrict 37124d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // matching when we do Thumb2. 371381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach if (ExtraToken != ".n") { 371481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 371581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 371681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach } 37175747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 37185747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 37195747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 37205747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 3721a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 37221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3723cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3724cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3725cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3726a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3727a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 3728b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 3729a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3730a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 37311355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3732cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3733cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3734cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3735a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3736a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 373716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3738cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 3739186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach SMLoc Loc = getLexer().getLoc(); 3740cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3741186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach return Error(Loc, "unexpected token in argument list"); 3742cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3743146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 374434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 3745ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3746d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 3747d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 3748d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 374920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // parse and adjust accordingly before actually matching. We shouldn't ever 375020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // try to remove a cc_out operand that was explicitly set on the the 375120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // mnemonic, of course (CarrySetting == true). Reason number #317 the 375220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach // table driven matcher doesn't fit well with the ARM instruction set. 375320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 3754ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3755ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 3756ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 3757ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 3758ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3759cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 3760cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 3761cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 376221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // a k_CondCode operand in the list. If we're trying to match the label 376321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach // version, remove the k_CondCode operand here. 3764cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 3765cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 3766cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3767cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 3768cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 3769cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 3770857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 3771857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 3772857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 3773857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 3774857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 3775857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 3776857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3777857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3778857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3779857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 3780857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 3781857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 378268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach delete Op; 378368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 378468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach } 378568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach // VCMP{E} does the same thing, but with a different operand count. 378668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 378768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm()) { 378868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 378968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 379068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach if (CE && CE->getValue() == 0) { 379168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.erase(Operands.begin() + 4); 379268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3793857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 3794857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3795857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3796934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 3797934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 3798934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 3799934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3800934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3801934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3802934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 3803934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 3804934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3805934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 3806934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3807934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3808934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 38099898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 3810ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3811ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3812189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 3813aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3814aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 3815aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 3816aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 3817aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 3818aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 3819aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 3820aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 3821aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 3822aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 3823aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 3824aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 3825aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 3826aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 3827aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 3828aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 3829aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 3830aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 383176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst, 383276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number. 383376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 383476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 383576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 383676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (OpReg == Reg) 383776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return true; 383876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 383976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return false; 384076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach} 384176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach 3842f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 3843f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 3844f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way? 3845f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm { 3846f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[]; 3847f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 3848f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 3849f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return ARMInsts[Opcode]; 3850f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach} 3851f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 3852189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 3853189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 3854189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 3855189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3856f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 3857f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc Loc = Operands[0]->getStartLoc(); 3858f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Check the IT block state first. 3859b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 3860b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // being allowed in IT blocks, but not being predicable. It just always 3861b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson // executes. 3862b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 3863f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned bit = 1; 3864f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (ITState.FirstCond) 3865f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = false; 3866f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach else 3867a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 3868f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // The instruction must be predicable. 3869f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (!MCID.isPredicable()) 3870f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "instructions in IT block must be predicable"); 3871f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 3872f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned ITCond = bit ? ITState.Cond : 3873f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCC::getOppositeCondition(ITState.Cond); 3874f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (Cond != ITCond) { 3875f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Find the condition code Operand to get its SMLoc information. 3876f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach SMLoc CondLoc; 3877f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach for (unsigned i = 1; i < Operands.size(); ++i) 3878f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 3879f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach CondLoc = Operands[i]->getStartLoc(); 3880f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(CondLoc, "incorrect condition in IT block; got '" + 3881f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 3882f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach "', but expected '" + 3883f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 3884f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } 3885c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach // Check for non-'al' condition codes outside of the IT block. 3886f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach } else if (isThumbTwo() && MCID.isPredicable() && 3887f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 388851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson ARMCC::AL && Inst.getOpcode() != ARM::tB && 388951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.getOpcode() != ARM::t2B) 3890f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(Loc, "predicated instructions must be in IT block"); 3891f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 3892189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 38932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 38942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 38952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 3896189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 3897189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3898189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 3899189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3900189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 3901189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 3902189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 3903189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3904189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 390514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 390614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 390714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 390814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 390914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 391014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 391114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 391214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 391314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 391453642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 391553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 3916189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 3917189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3918189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3919189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 3920189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 392114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 3922189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 3923189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3924189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3925fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 3926fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 3927fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 3928fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 3929fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 3930fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 3931fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 3932fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 393300c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 3934fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 393593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 393676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're parsing Thumb2, the .w variant is available and handles 393776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // most cases that are normally illegal for a Thumb1 LDM 393876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instruction. We'll make the transformation in processInstruction() 393976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // if necessary. 394076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 394193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 394293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 394393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 39447260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 39457260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 39467260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 3947aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 394876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 3949aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 3950aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 395193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 395276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 395393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 395493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 395576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we should not have writeback, there must not be a '!'. This is 395676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // true even for the 32-bit wide encodings. 3957aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 39587260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 39597260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 39607260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 396193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 396293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 396393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 396476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::t2LDMIA_UPD: { 396576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 396676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach return Error(Operands[4]->getStartLoc(), 396776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "writeback operator '!' not allowed when base register " 396876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach "in register list"); 396976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 397076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 39716dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 3972aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3973aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 3974aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3975aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 39766dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 39776dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 39786dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 3979aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3980aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 3981aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3982aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 39836dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 39846dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 39851e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 39861e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 39878213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 39881e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 39891e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 39901e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 39911e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 3992189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3993189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3994189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3995189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 3996189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3997f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 3998f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 3999f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4000f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 4001f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 4002f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 4003f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 4004f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 4005f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 4006f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 4007f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 4008f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4009f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4010f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 4011f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 4012f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 4013f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4014f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4015f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 4016f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4017f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 4018f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 4019f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 4020f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 4021f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 4022f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 4023f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 4024f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 4025f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4026f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 4027f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 4028f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 4029f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4030f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4031f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 4032f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 4033f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 403489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 40350f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 40360f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 40370f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 40380f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach // to encoding T1 if <Rd> is omitted." 40390f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 404089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 404189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 4042f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach case ARM::tSUBi8: 4043f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 4044f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 4045f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T2 if <Rd> is specified and encoding T2 is preferred 4046f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach // to encoding T1 if <Rd> is omitted." 4047f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 4048f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach Inst.setOpcode(ARM::tSUBi3); 4049f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach break; 405051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::tB: 405151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb conditional branch outside of an IT block is a tBcc. 405251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 405351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::tBcc); 405451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 405551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson case ARM::t2B: 405651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 405751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 405851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson Inst.setOpcode(ARM::t2Bcc); 405951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson break; 4060c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach case ARM::t2Bcc: 4061a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // If the conditional is AL or we're in an IT block, we really want t2B. 4062a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) 4063c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach Inst.setOpcode(ARM::t2B); 4064c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach break; 4065395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 4066395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 4067395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) 4068395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 40693ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 407076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach case ARM::tLDMIA: { 407176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If the register list contains any high registers, or if the writeback 407276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 407376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // instead if we're in Thumb2. Otherwise, this should have generated 407476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // an error in validateInstruction(). 407576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 407676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool hasWritebackToken = 407776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 407876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 407976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach bool listContainsBase; 408076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 408176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (!listContainsBase && !hasWritebackToken) || 408276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach (listContainsBase && hasWritebackToken)) { 408376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 408476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach assert (isThumbTwo()); 408576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 408676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // If we're switching to the updating version, we need to insert 408776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach // the writeback tied operand. 408876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach if (hasWritebackToken) 408976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach Inst.insert(Inst.begin(), 409076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach MCOperand::CreateReg(Inst.getOperand(0).getReg())); 409176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 409276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach break; 409376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach } 40948213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach case ARM::tSTMIA_UPD: { 40958213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // If the register list contains any high registers, we need to use 40968213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 40978213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // should have generated an error in validateInstruction(). 40988213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 40998213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach bool listContainsBase; 41008213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 41018213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 41028213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach assert (isThumbTwo()); 41038213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach Inst.setOpcode(ARM::t2STMIA_UPD); 41048213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 41058213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach break; 41068213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach } 41071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVi: { 41081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 41091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 41101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 41111ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(1).getImm() <= 255 && 4112c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 4113c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR) || 4114c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 41151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 41161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 41171ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't in the same order for tMOVi8... 41181ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 41191ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(ARM::tMOVi8); 41201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 41211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 41221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 41231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 41241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 41251ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 41261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 41271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 41281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 41291ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach case ARM::t2MOVr: { 41301ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 41311ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // request the 32-bit variant, transform it here. 41321ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 41331ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 41341ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(2).getImm() == ARMCC::AL && 41351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst.getOperand(4).getReg() == ARM::CPSR && 41361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 41371ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 41381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach // The operands aren't the same for tMOV[S]r... (no cc_out) 41391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach MCInst TmpInst; 41401ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 41411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 41421ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 41431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); 41441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 41451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach Inst = TmpInst; 41461ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 41471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach break; 41481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach } 4149326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach case ARM::t2SXTH: 415050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: 415150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: 415250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: { 4153326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // If we can use the 16-bit encoding and the user didn't explicitly 4154326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // request the 32-bit variant, transform it here. 4155326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4156326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4157326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst.getOperand(2).getImm() == 0 && 4158326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4159326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 416050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach unsigned NewOpc; 416150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach switch (Inst.getOpcode()) { 416250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach default: llvm_unreachable("Illegal opcode!"); 416350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 416450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 416550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 416650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 416750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach } 4168326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach // The operands aren't the same for thumb1 (no rotate operand). 4169326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach MCInst TmpInst; 4170326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.setOpcode(NewOpc); 4171326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); 4172326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); 4173326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 4174326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); 4175326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach Inst = TmpInst; 4176326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 4177326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach break; 4178326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach } 417989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 418089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 418189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 418289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 418389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 418489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 418589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 418689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 418789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 4188f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned OrigMask = Mask; 4189f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 419089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 419189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 419289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 419389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 419489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 419589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 419689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 4197f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach 4198f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // Set up the IT block state according to the IT instruction we just 4199f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach // matched. 4200f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach assert(!inITBlock() && "nested IT blocks?!"); 4201f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 4202f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.Mask = OrigMask; // Use the original mask, not the updated one. 4203f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.CurPosition = 0; 4204f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach ITState.FirstCond = true; 420589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 420689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 4207f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 4208f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 4209f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 421047a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 421147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 421247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 4213194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 4214194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 421547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 421647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 421747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 421847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 421947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 422047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 422147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 422247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 422347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 422447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 422547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 422647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 422747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 422847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 422947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 423047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 4231f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 4232f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach !inITBlock()) 423347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 4234f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 4235f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach inITBlock()) 4236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Match_RequiresNotITBlock; 423747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 4238194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 4239194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 4240194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 4241194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 4242194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 4243194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 4244194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 42454ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 4246194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 4247194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 4248194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 424947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 425047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 425147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 4252fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 4253fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 4254fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4255fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 4256fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 4257fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 425819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 4259193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 4260193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 426119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 4262e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 4263189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 4264189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 4265a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach if (validateInstruction(Inst, Operands)) { 4266a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Still progress the IT block, otherwise one wrong condition causes 4267a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // nasty cascading errors. 4268a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4269189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 4270a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach } 4271189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 4272f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 4273f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 4274f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 4275f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 4276a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // Only move forward at the very end so that everything in validate 4277a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // and process gets a consistent answer about whether we're in an IT 4278a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach // block. 4279a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach forwardITPosition(); 4280a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach 4281fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 4282fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 4283e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 4284e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 4285e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 4286e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 4287e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 4288e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 4289e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 4290e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 429116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4292e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 4293e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 4294e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 429516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4296e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 4297e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 4298e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 429947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 4300b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 430188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 430288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 4303f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach case Match_RequiresNotITBlock: 4304f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach return Error(IDLoc, "flag setting instruction only valid outside IT block"); 430547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 430647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 4307194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 4308194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 4309194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 4310194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 4311fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 431216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4313c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 4314146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 4315fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 4316fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 43171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 4318ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 4319ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 4320ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 43211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 4322515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 43231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 4324515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 43251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 4326515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 43271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 4328515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 43291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 4330ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4331ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4332ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 43331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 4334ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 43351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 4336ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 4337ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 4338ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 4339ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 4340ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 4341ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4342aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 4343ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4344ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 4345ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 434616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4347ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 4348ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 4349ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 4350b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4351ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4352ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 4353ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 4354b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4355ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 4356ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 4357ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 43581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 4359515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 43601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 4361515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4362515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4363b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4364515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4365515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 4366515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 4367515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4368515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4369515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4370515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 43711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 4372515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 43731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 43746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 43756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 43766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 43776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 43786469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 43796469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 43806469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 43816469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 43826469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 43836469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 43846469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 43856469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 43866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 43876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4388515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 4389515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 4390b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4391515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 43926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 43936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 43946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 43956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 43966469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4397642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 4398642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 4399642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 4400515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4401515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4402515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 44031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 4404515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 44051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 440618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4407515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 4408515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 440938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 441058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 4411b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 441258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 44139e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 4414515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4415515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 4416515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4417515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 441818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4419b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4420515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4421515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 4422515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 4423515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4424515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4425515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 44261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 4427515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 44281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 442918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4430515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 4431515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 443218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 443358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 4434b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 443558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 4436b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4437515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 4438515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 4439515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 4440515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 444118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4442b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4443515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 444432869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 444598447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (!isThumb()) 4446ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 444798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 444832869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 444998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach if (isThumb()) 4450ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 445198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 4452eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 44532a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 4454515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 4455515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 4456515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 445790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 445890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 44599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 4460ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 446194b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 446294b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 446390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 4464ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 44653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 44660692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 44670692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 44683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 4469