ARMAsmParser.cpp revision 0da10cf44d0f22111dae728bb535ade2283d976b
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 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 52ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 550d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *applyPrefixToExpr(const MCExpr *E, 619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 63a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 71515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 7389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool &CarrySetting, unsigned &ProcessorIMod, 7489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask); 751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 76fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 7716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 78ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 79ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 80ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 81ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 82ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 83ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 84ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 8547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 8647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 8747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 88194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 89194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 90194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 9132869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 92ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 93ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 9432869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 95ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 96a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 97a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 990692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1000692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 102a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 103a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 10489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 10543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 106f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1108bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 11143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1128bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 11343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1148bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 115f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 116f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 117f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 118f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 119f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 120f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 121f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 122f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 123c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 124580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 126293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 128251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 129ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 130ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 1311355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1339ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 1349ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &); 135548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 136548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 138ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1397b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1407b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 15114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 15214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 153623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 154623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 15588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 15688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 157189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 158189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 159189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 160f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach void processInstruction(MCInst &Inst, 161f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 162d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 163d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 164189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 165ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 16647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 167194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 168194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 169194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 17047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 17147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 172ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 17394b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 174ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 17532869205052430f45d598fba25ab878d8b29da2dEvan Cheng 176ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 177ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 178ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 179ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 1811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 1821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 183189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 1841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 1851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 18647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 18747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 1881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 1891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 191ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 19216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 19316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1943a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1953a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 198146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 199762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 2008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 201d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 20289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITCondMask, 203fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 204fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 205cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 206706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 2078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 2087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIndexRegister, 209584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 210a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 2118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 2128d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 2130f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 2140f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 215e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 21692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 217580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImmediate, 2187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotateImmediate, 219293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach BitfieldDescriptor, 2208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 221a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 222a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 223762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 22424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 225a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 226a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 227a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2288462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2308462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2318462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 232fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 233fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 234fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 235fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 23689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask:4; 23789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } ITMask; 23889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 23989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 24089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARM_MB::MemBOpt Val; 24189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } MBOpt; 24289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 24389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach struct { 244a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 245a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 246a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 247a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 248584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 249584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 250584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 251584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 252a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 253a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 254a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 255a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 256a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 257a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 258a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 259a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2608155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 261cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 262cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 26316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2646a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 265a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 266a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 2687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 2697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 2707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 2717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 2720d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm; // shift for OffsetReg. 2737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 278f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 279f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 280f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 2817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 2827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 284580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 286580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 287e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 288e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 289e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 290e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 291e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 292af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 29392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 29492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 29592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 29692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 297af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 2987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 2997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 3007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 301293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 302293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 303293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 304293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 30616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 307146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 308146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 310762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 313762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 3148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 3158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3168462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 31789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ITCondMask: 31889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = o.ITMask; 31989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 320762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 3218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 322762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 323d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 324762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 325762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 326762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3278d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 3280f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 3290f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 33024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 3318d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 332fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 333fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 334fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 335fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 336762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 337762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 338762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 339706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 340706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 341706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 342762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 343762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 344762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 3467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 3477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 348584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 349584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 350584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 351a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 352a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 3530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 354580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 355580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 3560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 357e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 358af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 359e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 36092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 361af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 36292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 3637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 3647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 3657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 366293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 367293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 368293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 369762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 370762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 37116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 372762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 373762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 374762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 375762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 376a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 382fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 383fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 384fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 385fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 386fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 387a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 388a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 389a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 390a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 391a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 392a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3936aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3947729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 395a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 396a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3975fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 40024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 4018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 4028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 403cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 404cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 405cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 406cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 407cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 408706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 409706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 410706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 411706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 412706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 413a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 414a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 415a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 416a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 417a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 418584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 419584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 420584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 421584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 422584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 423fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 424fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 4258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 426d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 42789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool isITMask() const { return Kind == ITCondMask; } 42889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach bool isITCondCode() const { return Kind == CondCode; } 4293483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 43072f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 43172f39f8436848885176943b0ba985a7171145423Jim Grosbach if (Kind != Immediate) 43272f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 43372f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 43472f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 43572f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 43672f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 43772f39f8436848885176943b0ba985a7171145423Jim Grosbach } 43872f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 43972f39f8436848885176943b0ba985a7171145423Jim Grosbach if (Kind != Immediate) 44072f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 44172f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 44272f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 44372f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 44472f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 44572f39f8436848885176943b0ba985a7171145423Jim Grosbach } 4466b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 4476b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4486b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4496b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4506b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4516b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 4536b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 45483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 45583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 45683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 45783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 45883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 45983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 46083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 46183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 46283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 46383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 46483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 46583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 46683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 46783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 46883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 46983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 4707c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 4717c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (Kind != Immediate) 4727c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 4737c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4747c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 4757c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 4767c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 4777c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 478f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 479f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (Kind != Immediate) 480f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 481f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 482f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 483f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 484f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 485f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 4864a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 4874a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (Kind != Immediate) 4884a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 4894a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4904a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 4914a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 4924a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 4934a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 494fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 495fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 496fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 497fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 498fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 499fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 500fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 501fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 502ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 503ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 504ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 505ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 506ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 507ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 508ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 509ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 510ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 511ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 512ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 513ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (Kind != Immediate) 514ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 515ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 516ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 517ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 518ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 519ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 52070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 52170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (Kind != Immediate) 52270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 52370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 52470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 52570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 52670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 52770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 528f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 529f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 530f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 531f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 532f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 533f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 534f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 535f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 536f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 537f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 538f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 539f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 540f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 541f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 542f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 543f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 5446bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 5456bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 5466bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 5476bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5486bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 5496bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 5506bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 5516bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 5526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 5536b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 5546b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5556b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5586b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 5596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 560c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 561c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Kind != Immediate) 562c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 563c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 564c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 565c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 566c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 567c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 568b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 5698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 5700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 5710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 57214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 573706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 57414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 575580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isShifterImm() const { return Kind == ShifterImmediate; } 576af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 577af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 5787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach bool isRotImm() const { return Kind == RotateImmediate; } 579293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach bool isBitfield() const { return Kind == BitfieldDescriptor; } 580f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; } 581f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 582f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 583f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 5847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemNoOffset() const { 5857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 586ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 5877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 5887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 589ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 5907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 5917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 592ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 5937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 5947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return true; 5957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 5967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 5997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 600039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 601039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Kind != Immediate) 602039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 603039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 604039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 605039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 606039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 607039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 608039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 6092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 6102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Memory) 6112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 6122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 6132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.ShiftType != ARM_AM::no_shift) return false; 6142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 6152fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.OffsetRegNum) return true; 6162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 6172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetImm) return true; 6182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 6202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 6212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 6222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Immediate && Kind != PostIndexRegister) 6232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 6242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) 6252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 6262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 6272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 6292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 630251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 631251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 6322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 6337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 6347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 635ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 6367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 6377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return false; 6387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 6397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6410da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 6420da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson Val == INT32_MIN; 6437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 6447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 6457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum) 646ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 647ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 648ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 6497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 6507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 6517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 6527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 6537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftType != ARM_AM::no_shift) 65487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 65560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return isARMLowRegister(Mem.BaseRegNum) && 65660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum)); 65760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 65860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 65960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 66060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 66160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 66260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 66360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (!Mem.OffsetImm) return true; 66460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 665ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 666ecd858968384be029574d845eb098d357049e02eJim Grosbach } 66738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 66838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 66938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 67038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 67138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 67238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (!Mem.OffsetImm) return true; 67338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 67438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 67538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 67648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 67748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 67848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 67948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 68048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 68148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (!Mem.OffsetImm) return true; 68248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 68348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 68448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 685ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 686ecd858968384be029574d845eb098d357049e02eJim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP) 687ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 688ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 689ecd858968384be029574d845eb098d357049e02eJim Grosbach if (!Mem.OffsetImm) return true; 690ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 691ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 692505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 6937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 6947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 695f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 6967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 6977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 700f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 7017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 70209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 70309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 70409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 70509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) 70609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 70709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 7087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 709ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 7107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 7117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 7127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 7130da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 7147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 7157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 7167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Immediate) 7177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 7187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 719ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 7207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 72163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return (Val > -256 && Val < 256) || (Val == INT32_MIN); 722ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 7237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 724584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 725a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 7263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 7273483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 72814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 72914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 73014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 73114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 7323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 7333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 7343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 7353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 7363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 7378462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 738345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 7398462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 74004f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 74104f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 7428462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 7438462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 744fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 745fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 746fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 747fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 748fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 74989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITMaskOperands(MCInst &Inst, unsigned N) const { 75089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 75189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 75289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 75389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 75489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 75589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 75689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 75789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 75889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 759fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 760fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 761fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 762fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 763fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 764d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 765d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 766d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 767d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 768d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 769a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 770a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 771a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 772a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 773a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 774af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 775e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 776af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 777af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 778af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 779e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 780af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 781e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 782e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 783af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 784152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 785af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 786af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 78792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 788af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 78992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 79092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 79192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 792580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 7930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 794580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 795580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 7960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 7970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 79887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 7997729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 8005fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 8015fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 8027729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 8037729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 80487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 80587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 8060f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 8070f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 8080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 8090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 8100f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 8110f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 8120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 8130f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 8147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 8157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 8177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 8187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 8197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 820293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 821293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 822293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 823293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 824293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 825293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 826293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 827293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 828293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 829293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 830293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 8313483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 8326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 8346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 8356b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 83672f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 83772f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 83872f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 83972f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 84072f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 84172f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 84272f39f8436848885176943b0ba985a7171145423Jim Grosbach } 84372f39f8436848885176943b0ba985a7171145423Jim Grosbach 84472f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 84572f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 84672f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 84772f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 84872f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 84972f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 85072f39f8436848885176943b0ba985a7171145423Jim Grosbach } 85172f39f8436848885176943b0ba985a7171145423Jim Grosbach 8526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 8536b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8546b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 8556b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 8566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 85783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 85883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 85983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 86083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 86183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 86283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 8637c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8647c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 8657c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 8667c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 8677c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 86883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 86983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 87083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 87183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 872f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 873f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 874f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 875f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 876f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 877f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 878f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 879f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 8804a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 8814a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 8824a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 8834a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 8844a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8854a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 8864a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 8874a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 888fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 889fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 890fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 891fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 892fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 893ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 894ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 895ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 896ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 897ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 898ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 899ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 900ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 90170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 90270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 90370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 90470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 90570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 90670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 90770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 90870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 90970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 910ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 911ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 912f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 913f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 914f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 915f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 916f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 917f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 918f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 919f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 920f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 921f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 922f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 923f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 924f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 925f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 9266bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 9276bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 9286bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 9296bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 9306bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 9316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 9323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 9333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 9343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 93516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 936c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 937c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 938c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 939c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 940c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 941706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 942706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 943706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 944706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 945706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 9467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 9477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 949505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 950505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 9517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 9527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 9537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetRegNum) { 9557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 9577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 9587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 9597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 9607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 9617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 9627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 9637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 964dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 965ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 9667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 9687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 969ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 970ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 971039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 972039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 973039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 974039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 975039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 976039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 977039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 978039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 979039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 980039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 981039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 982039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 983039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 984039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 9852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 9862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 9872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetRegNum) { 9892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 9912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 9922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 9932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 9942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 9952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 9962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 9972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 9982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 10012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 10032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 10042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 10052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) { 10072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 10082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 10092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 10102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1011251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 10122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 10132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 10142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 10152fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 10162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 10172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 10182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 10192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 10202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 1021251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 10222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 10232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 10252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 10267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 10277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 10297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 10307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 10317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 10327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 10337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 10347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 10357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 10387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 10397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 10407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 10427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1044ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1045ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 10467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 10477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 104809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 104909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate) { 105009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 105109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 105209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 105309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 105409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 105509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 10567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 10577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 106092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 10617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 10627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 10637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 10640d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 10657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 10677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1069d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 10707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 10717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 107414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 10753483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 107660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 107760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 107860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 107960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 108060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 108148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 108248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 108338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 108438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 108538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0; 108638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 108738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 108838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 108938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 109048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 109148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 109248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0; 109348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 109448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 109560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 109660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1097ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1098ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1099ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 1100ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1101ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1102ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1103ecd858968384be029574d845eb098d357049e02eJim Grosbach 11047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 11057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 11067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 11077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 11087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 11097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 111063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (Imm == INT32_MIN) Imm = 0; 11117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 11127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1113f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1114ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 11157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 11167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 11177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1118f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1119f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1120f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1121f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1122f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1123f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1124f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1125f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1126f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1127f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1128f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1129f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1130ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1131ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1132584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1133584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1134584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1135584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1136584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1137a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1138a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1139a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1140a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1141a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1142b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1143b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 114489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 114589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ARMOperand *Op = new ARMOperand(ITCondMask); 114689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->ITMask.Mask = Mask; 114789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->StartLoc = S; 114889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Op->EndLoc = S; 114989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Op; 115089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 115189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 11523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 11533a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 1154345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1155345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1156345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 11573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1158345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1159345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1160fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 1161fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 1162fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1163fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1165fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1166fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1167fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1168fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 1169fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 1170fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1171fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1172fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1173fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1174fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1175fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1176d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 1177d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 1178d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1179d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1180d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1181d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1182d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1183d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 11843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 11853a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 1186762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1187762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1188762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1189762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 11903a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1192a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 119350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 11943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 1195762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1196762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1197762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 11983a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1201e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1202e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1203e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1204e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1205e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 1206e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 1207af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1208af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1209af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1210af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1211e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1212e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1213e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1214e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1215e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 121692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 121792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 121892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 121992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 122092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 1221af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1222af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1223af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 122492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 122592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 122692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 122792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 122892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1229580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 12300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 1231580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ARMOperand *Op = new ARMOperand(ShifterImmediate); 1232580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1233580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 12340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 12350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 12360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 12370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 12380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 12397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 12407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach ARMOperand *Op = new ARMOperand(RotateImmediate); 12417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 12427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 12437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 12447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 12457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 12467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1247293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1248293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 1249293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 1250293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1251293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1252293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1253293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1254293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1255293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1256293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 12577729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 12585fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1259cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 12600f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 12610f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1262275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 1263275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 12640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 1265275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 1266275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 12670f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 12680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 12690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 12705fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 12717729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 127224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1273cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1274cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1275cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 12768d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 12778d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 12788d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 12793a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 12803a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 1281762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1282762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1283762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 12843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1285cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1286cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 12877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 12887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 12897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 12907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 12910d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 12927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 12933a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 12943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 1295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 12967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetImm = OffsetImm; 12977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetRegNum = OffsetRegNum; 1298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 12990d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Op->Mem.ShiftImm = ShiftImm; 13007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.isNegative = isNegative; 13017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 13027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 13037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 13047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 130516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1306f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1307f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1308f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 13097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 13107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARMOperand *Op = new ARMOperand(PostIndexRegister); 13117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1312f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1313f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1314f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1315762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1316762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 13173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1319706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1320706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1321706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1322706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1323706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1324706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1325706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1326706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1340584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1341584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1342584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1344a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1345a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1346a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1347b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1348fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 1349fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 13506a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1351fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1352d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1353d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1354d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 135589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ITCondMask: { 135689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)", 135789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)", 135889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach "(tee)", "(eee)" }; 135989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert((ITMask.Mask & 0xf) == ITMask.Mask); 136089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 136189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 136289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 1363fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1364fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1365fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1366fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1367fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1368fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1369584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1370584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1371584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1372fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1373fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1374fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1375706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1376706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1377706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1378fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 13796ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 13807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << " base:" << Mem.BaseRegNum; 13816ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1382fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 13837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 1384f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1385f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1386f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1387f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1388f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1389f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 13907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 1391a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1392a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1393a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1394a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1395a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1396a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1397a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1398a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1399a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1400fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 140150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1402fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1403580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 1404580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1405580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1406e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1407e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 140892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1409af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1410af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1411af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1412af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1413e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 14140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 141592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 141692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1417af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1418af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1419af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 142092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 142192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 14227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 14237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 14247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 1425293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 1426293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1427293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1428293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 14290f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 14300f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 14310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 14328d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 14338d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 14345fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 14355fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 14367729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 14377729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 14387729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 14398d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 14408d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 14418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 14428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 14438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1444fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1445fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1446fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1447fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1448fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 14493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 14503483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 14513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 14523483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 14533483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 14543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 14553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 14563483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 145769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 145869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 14591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1460bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1461bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1462bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1463bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 14649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1465e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1466e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 14673a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 14681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 146918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 14707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1471d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1472a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1473a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 14740c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 14750c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 14760c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 14770c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 14780c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 14790c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 14800c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 14810c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 14820c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 14830c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 14840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 14850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 148669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1487b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1488e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1489e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1490d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 149119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 149219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 149319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 149419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 149519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 14960d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 14970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 14980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 14990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 15000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 15010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 15020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 15030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 15040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 15050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 15060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 15070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 15080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 15090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 15100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 15110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 15120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 151319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 15140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1515e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1516e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1517e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1518e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1519e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1520eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1521e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1522e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1523e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1524e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1525e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1526e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1527e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1528e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1529e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1530e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1531e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1532e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1533e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1534e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1535e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1536e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 153719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 153819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 153919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 154019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1541e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1542e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 154319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 154419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 154519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 154619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1547e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1548e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1549e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1550e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1551e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1552e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1553e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 155419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 155519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1556e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1557e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 15581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1559e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 156019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 156119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 156219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 156319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 156419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 156519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1566e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 156719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 156819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1569e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1570e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 157192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 157292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1573af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 15740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 157592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 157692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 157792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 15780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 157919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 15800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 15810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 15820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 158350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 158450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 158550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1586e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1587e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1588e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 158950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 15901355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1591e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 15921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1593e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 159450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1595d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 159650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1597a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1598e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1599e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 160050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 160150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1602e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 160399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 160499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 160550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1606a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1608fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1609fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1610fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1611fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1612e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1613e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1614e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1615e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1616e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1617fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1618e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1619e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1620e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1621e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1622e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1623e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1624e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1625e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1626e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1627e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1628e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1629e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1630e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1631e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1632e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1633e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1634fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1635e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1636e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1637e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1638e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1639e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1640e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1641e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1642e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1643e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1644e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1645e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1646e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1647e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1648e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1649e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1650e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 165189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction. 165289df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 165389df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 165489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 165589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach const AsmToken &Tok = Parser.getTok(); 165689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (!Tok.is(AsmToken::Identifier)) 165789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 165889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned CC = StringSwitch<unsigned>(Tok.getString()) 165989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("eq", ARMCC::EQ) 166089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ne", ARMCC::NE) 166189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hs", ARMCC::HS) 166289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cs", ARMCC::HS) 166389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lo", ARMCC::LO) 166489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("cc", ARMCC::LO) 166589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("mi", ARMCC::MI) 166689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("pl", ARMCC::PL) 166789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vs", ARMCC::VS) 166889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("vc", ARMCC::VC) 166989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("hi", ARMCC::HI) 167089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ls", ARMCC::LS) 167189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("ge", ARMCC::GE) 167289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("lt", ARMCC::LT) 167389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("gt", ARMCC::GT) 167489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("le", ARMCC::LE) 167589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Case("al", ARMCC::AL) 167689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach .Default(~0U); 167789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (CC == ~0U) 167889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_NoMatch; 167989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.Lex(); // Eat the token. 168089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 168189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 168289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 168389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return MatchOperand_Success; 168489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach} 168589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 168643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1687fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1688fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1689f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 169043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1691e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1692e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1693e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1694e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1695fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1696e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1697f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1698e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1699e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1700fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1701f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1702fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1703fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 170443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1705fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1706fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1707f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 170843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1709fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1710fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1711fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1712fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1713fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1714fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1715f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1716fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1717fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1718fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1719f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1720e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1721e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1722c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1723c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 172450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 17251355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 172618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1727a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1728e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 172916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 17307729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 17317729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 17325fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1733d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 17347729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1735e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 17367729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1737d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 173818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1739d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1740c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1741c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 174250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1743c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1744e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 17451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNum = tryParseRegister(); 1746c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1747c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 174850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1749c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1750d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1751e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1752e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1753e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1754e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1755e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1756e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1757e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1758e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1759e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1760e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1761e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 17627729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 17637729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1764e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1765e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 176618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1767c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1768c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 176950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1770c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1771d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1772e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1773e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 177403f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1775e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 17768e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 177711e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach unsigned HighRegNum = 0; 177811e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach BitVector RegMap(32); 177911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 178011e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach const std::pair<unsigned, SMLoc> &RegInfo = Registers[i]; 17817caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1782e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 17838e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1784e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 178550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1786e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1787e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 17888e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1789e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1790e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1791e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 179211e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach RegMap.set(Reg); 17938e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1794e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1795e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 179650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 179750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1798d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1799d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 180043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1801f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 180243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1803706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1804706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1805706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1806706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1807706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1808706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1809706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1810706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1811032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 1812706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1813032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 1814706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1815706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1816032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 1817706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1818032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 1819706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1820706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1821706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1822706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1823706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1824f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1825706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1826706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1827706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1828f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1829706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1830706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 183143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1832a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 183343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1834a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1835a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1836a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1837a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1838a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1839a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1840a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1841a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1842a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1843a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1844a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1845a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1846a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1847a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1848a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1849a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1850a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1851a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1852a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1853a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1854a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1855a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1856a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1857a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1858584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1859584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 186043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1861584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 186243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1863584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1864584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1865584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1866584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1867584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1868584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1869584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1870584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1871b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1872584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1873584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1874584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1875584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1876584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1877584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1878584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1879584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1880584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1881584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1882b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 1883584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1884584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1885584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1886584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 18874b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1888584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1889584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1890584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1891584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 18924b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1893584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 189456926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 189556926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1896584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1897584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1898584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1899584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1900584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1901584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1902584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1903584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1904584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1905584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1906584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1907584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1908584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1909584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1910584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1911584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1912584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1913584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1914584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1915584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1916584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1917584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1918584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1919584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1920584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1921584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1922584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1923584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1924a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1925a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1926f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1927f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1928f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 1929f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1930f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1931f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1932f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1933f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1934f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 1935f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 1936f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 1937f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 1938f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1939f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1940f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1941f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 1942f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1943f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 1944f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1945f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1946f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1947f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1948f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 1949f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1950f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 1951f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 1952f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1953f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 1954f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1955f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1956f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1957f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 1958f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 1959f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1960f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1961f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1962f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 1963f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 1964f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1965f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1966f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1967f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1968f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1969f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 1970f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 1971f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1972c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1973c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1974c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1975c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 1976c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1977c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1978c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1979c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1980c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 1981c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 1982c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 1983c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 1984c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 1985c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1986c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 1987c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1988c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1989c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1990c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1991c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 1992c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 1993c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 1994c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 1995c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1996580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1997580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 1998580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 1999580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 2000580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 2001580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2002580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2003580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 2004580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 2005580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 2006580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2007580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2008580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2009580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 2010580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 2011580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 2012580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 2013580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 2014580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 2015580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 2016580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 2017580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2018580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2019580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 2020580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2021580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 2022580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2023580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2024580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2025580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2026580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 2027580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2028580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 2029580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 2030580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 2031580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 2032580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2033580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2034580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2035580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 2036580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 2037580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2038580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2039580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2040580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 2041580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 2042580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2043580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 2044580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 2045580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2046580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2047580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // asr #32 encoded as asr #0. 2048580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 2049580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 2050580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 2051580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 2052580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 2053580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 2054580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2055580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 2056580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2057580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 2058580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 2059580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 2060580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 2061580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 2062580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 20637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 20647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 20657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 20667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 20677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 20687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 20697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 20707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 20717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 20727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 20757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") { 20767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 20777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 20807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 20817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 20827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 20837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 20847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 20877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 20887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 20897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 20907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 20917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 20927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 20957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 20967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 20977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 21007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 21017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 21027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 21037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 21047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 21057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 21067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 21077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 21087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 21097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 21107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 21117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 21127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 21137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 21147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2115293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2116293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2117293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2118293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2119293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2120293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2121293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2122293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2123293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2124293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2125293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2126293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2127293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2128293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2129293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2130293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2131293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2132293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2133293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2134293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2135293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2136293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2137293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2138293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2139293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2140293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2141293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2142293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2143293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2144293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2145293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2146293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2147293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2148293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2149293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2150293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2151293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2152293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2153293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2154293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2155293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2156293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2157293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2158293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2159293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2160293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2161293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2162293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2163293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2164293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2165293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2166293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2167293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2168293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2169293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2170293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2171293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2172293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2173293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2174293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2175293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2176293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2177293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2178293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2179293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2180293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 21817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 21827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 21837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2184f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2185f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2186f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 21877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 21897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 21907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 21917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 21927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 21937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 219416578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 21957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 21967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 21977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 21987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 21997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 22007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 220116578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 22027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 22037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 22047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 22057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 22067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 22077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 22087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 22097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 22107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 22117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 22127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 22137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2214f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2215f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 22160d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 22170d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 22180d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 22190d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 22200d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2221f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2222f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2223f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 22247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 22257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 22267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 22277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2228251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2229251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2230251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2231251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2232251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2233251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2234251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2235251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2236251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2237251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2238251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2239251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2240251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2241251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2242251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2243251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2244251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2245251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2246251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2247251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2248251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2249251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2250251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2251251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2252251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2253251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2254251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2255251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2256251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2257251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2258251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2259251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2260251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2261251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2262251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2263251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2264251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2265251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2266251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2267251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2268251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2269251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2270251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2271251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2272251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2273251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2274251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2275251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2276251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2277251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2278251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2279251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2280251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2281251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2282251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2283251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2284251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2285251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2286251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2287251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2288251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2289251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2290251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2291251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2292251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2293251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 2294251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2295251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2296251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 2297251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 22981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2299ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2300ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2301ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 23021355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2303ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2304ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2305ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2306ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2307ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2308ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 23097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2310ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2311ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2312ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2313ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 23149ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 23159ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands 23169ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one. 23179ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser:: 23189ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 23199ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23209ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 23219ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 23229ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson // Create a writeback register dummy placeholder. 23239ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson Inst.addOperand(MCOperand::CreateImm(0)); 23249ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 23259ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 23269ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 23279ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson return true; 23289ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson} 23299ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 23309ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson 2331548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2332548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2333548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2334548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 2335548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2336548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2337548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 2338548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2339548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2340548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2341548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2342548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 2343548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 2344548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 23451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2346ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2347ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2348ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 23491355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2350ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2351ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2352ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2353548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2354548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2355548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 23567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 23577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 23587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 23597b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 23607b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 23617b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 23627b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 23637b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 23647b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23657b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 23667b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 23677b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 23687b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 23697b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 23707b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 23717b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 23727b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 23737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 23747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 23757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 23767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 23777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 23787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2380ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 23817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 23827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 23837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 23847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 23857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 23867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 23877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2388ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2389ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2390ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2391ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 23927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2393ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2394ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2395ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 23967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 23977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2399aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2400ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2401ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 24027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 24037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 24047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 24057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 24067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 24077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 24087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 24097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 2410aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 24117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 24127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 24137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 24147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 24157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 24167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 24177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 24187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 24197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 24207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 24217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 24227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 24237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 24247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 24257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2426ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2427ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2428ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2429ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 24307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2431ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2432ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2433ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 24347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 24357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2436ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2437ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 24387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2439ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 24407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 24417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 24427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 24437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 24447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2445ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2446ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2447ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2448ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 24492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 24502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 24512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 24522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 24532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 24542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 24552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 24562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 24572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 24582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 24592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 24602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 24612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 24622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 24632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 24642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 24652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 24662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 246714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 246814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 246914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 247014605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 247114605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 247214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 247314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 247414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 247514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 247614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 247714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 247814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 247914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 248014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 248114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 248214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 248314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 248414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 2485623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2486623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2487623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2488623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 2489623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2490623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2491623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2492623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 2493623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2494623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2495623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2496623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 2497623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 2498623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 249988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 250088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 250188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 250288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 250388ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 250488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 250588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 250688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 250788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 25087a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 25097a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 25107a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 25117a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 251288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 25137a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 251488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 251588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 251688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 251788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 251888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 25197a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // If we have a three-operand form, use that, else the second source operand 25207a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // is just the destination operand again. 25217a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach if (Operands.size() == 6) 25227a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 25237a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach else 25247a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach Inst.addOperand(Inst.getOperand(0)); 252588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 252688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 252788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 252888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 2529623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2530e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 25319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 253250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 25337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2534762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 253518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 2536a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 2537762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2538b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 2539a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 254018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 25411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 25427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 25437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 2544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 25450571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 25460571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 25470571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 25487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 25490571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 25507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 2551762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 2552b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 2553a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 25547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 25557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, false, S, E)); 255603f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 25577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 25587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 255950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 25607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 25617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 256250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 25637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If we have a '#' it's an immediate offset, else assume it's a register 25647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 25657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 25667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 25677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 256850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 25690da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson bool isNegative = getParser().getTok().is(AsmToken::Minus); 25707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 25717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 25727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 257305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 25747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 25757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 25767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 25777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 25787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 25797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 25807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 25810da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson // If the constant was #-0, represent it as INT32_MIN. 25820da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson int32_t Val = CE->getValue(); 25830da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson if (isNegative && Val == 0) 25840da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson CE = MCConstantExpr::Create(INT32_MIN, getContext()); 25850da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson 25867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 25877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 25887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 25897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 25907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 259105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 25927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 25937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 25947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 25957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::no_shift, 0, false, S,E)); 2596a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 25977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 25987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 25997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 26007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 26017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 2602762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 26037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 26047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 26059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 2606d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 26077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 26087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 26097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 26107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 26117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 26127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 26137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 26147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 26157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 26169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 26177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 26187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 26197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 26207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 26217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 26227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 26237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 26240d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 26257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 26267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 26270d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 26287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 26299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 263016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 26317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 26327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 26337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 26347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 26357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 26367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 26377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 26380d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach ShiftType, ShiftImm, isNegative, 26397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 26407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2641f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 2642f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 2643f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 2644f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2645f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 2646f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 26479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 26489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 26499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 26509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 26517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 2652a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 2653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 26547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 26557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 26567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 26577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 265818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2660a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 266138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 2662a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 26630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 2664a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 26650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 2666a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 26670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 2668a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 26690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 2670a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 26710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 2672a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 26737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 2674b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 2675a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 26767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 26777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 26787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 26797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 26807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 26817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 26827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 26837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 26847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 26859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 26867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 26877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 26887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 26897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 26907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 26917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 26927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 26937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 26947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 26957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 26967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 26977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 26987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 26997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 27007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 27017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 2702a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2703a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 2704a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2705a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 27069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 27079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 27081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2709fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 2710762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 2711fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2712fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 2713fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 2714f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2715f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 2716fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 2717f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 2718f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 2719f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 2720f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 2721f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 2722fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2723a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 2724146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 2725146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 272650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 272719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 27281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 272950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 27300d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 273119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 27320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 273319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 273419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 2735e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2736e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 2737e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 273819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 273967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 274067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 2741515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 2742515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 2743515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 2744762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2745515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 274650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2747762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 274850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 274950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 275050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 2751a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 27521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 2753d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 27541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 275563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson case AsmToken::Hash: { 2756079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 2757079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2758762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2759b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 276063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson bool isNegative = Parser.getTok().is(AsmToken::Minus); 2761515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 2762515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 276350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 276463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 276563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (!CE) { 276663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson Error(S, "constant expression expected"); 276763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson return MatchOperand_ParseFail; 276863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 276963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson int32_t Val = CE->getValue(); 277063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson if (isNegative && Val == 0) 277163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 2772762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 277350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 277450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 277563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson } 27769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 27779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 27787597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 27797597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 27807597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 27811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 27829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 27839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27847597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 27857597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 27869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 27879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27887597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 27897597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 27909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 27917597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 27929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 27939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 2794a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2795a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2796a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 27971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 27987597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 27991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 28007597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 28019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 28038a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 28049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 28059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 28079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 28089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 28099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 28109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 28129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 28137597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 28149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 28157597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 28169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 28179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 28189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 28199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 28209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 28219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 28239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 28249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 28259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 28269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 28279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 28289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 28299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 28311355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E, 28329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 28339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 28349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 28359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 28369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 28379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 28399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 28409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 28419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 28429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 28439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 28459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 28469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 28489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 28499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 28519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 28529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 28549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 28559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 28579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 28581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant); 28599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 28609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 28619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 28629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 28649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 28659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 28669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 28679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 28689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 28699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 28709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 2871352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 2872352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 2873352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 2874badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 287589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases. 28761355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 28775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 28785f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 287989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned &ProcessorIMod, 288089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef &ITMask) { 2881352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 2882352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 2883a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 2884352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2885badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 2886352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 2887352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 28885f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 28895f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 28905f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 28915f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 28925f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 28935f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 28945f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 28955f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2896352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2897badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 28983f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 28993f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 2900ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 290171725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 290204d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 290304d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "sbcs") { 29043f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 29053f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 29063f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 29073f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 29083f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 29093f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 29103f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 29113f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 29123f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 29133f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 29143f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 29153f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 29163f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 29173f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 29183f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 29193f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 29203f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 29213f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 29223f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 29233f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 29243f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 29253f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 29263f00e317064560ad11168d22030416d853829f6eJim Grosbach } 292752925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 2928345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2929352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 2930352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 2931352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 293200f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 29335f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 29345f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 29355f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 2936e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 2937e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 2938352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2939352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 2940352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 2941352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2942a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 2943a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 2944a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 2945a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 2946a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 2947a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2948a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 2949a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 2950a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2951a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 2952a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2953a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 2954a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2955a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2956a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 295789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The "it" instruction has the condition mask on the end of the mnemonic. 295889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic.startswith("it")) { 295989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ITMask = Mnemonic.slice(2, Mnemonic.size()); 296089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mnemonic = Mnemonic.slice(0, 2); 296189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 296289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 2963352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2964352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 29653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 29663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 29673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 29683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 29693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 2970fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 29711355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2972fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 2973eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2974eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2975eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2976eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2977be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2978eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2979eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 29802c3f70e5d4b4f179f21ed1b2ba14674f9d65c9b0Jim Grosbach Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "neg" || 2981194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // FIXME: We need a better way. This really confused Thumb2 2982194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // parsing for 'mov'. 2983ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 2984eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 2985eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 2986eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 2987eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 29883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 2989eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2990eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2991eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2992eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 29935f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2994c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Mnemonic == "setend" || 29950780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 29964af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw") && 29974af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 29984af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 29994af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach !isThumb()) || 30005f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 30013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 30023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 30033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 30043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 3005fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 3006ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 3007fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 300863b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 3009fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 3010badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 3011badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3012d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 3013d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3014d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3015d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 3016d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 3017d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 3018d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 3019d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 3020d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 3021d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 3022d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 3023d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (Mnemonic == "mov" && Operands.size() > 4 && 3024d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 3025d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 3026d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3027d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 30283912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 30293912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 30303912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 30313912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 30323912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 30333912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 30343912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 30353912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 303672f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 303772f39f8436848885176943b0ba985a7171145423Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm} instruction. 303872f39f8436848885176943b0ba985a7171145423Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 6 && 303972f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 304072f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 304172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 304272f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 304372f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 3044f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 3045f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 3046f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 3047f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 3048f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 3049f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 3050f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 305172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 305272f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 305372f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 305472f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 30553912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 3056d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 3057d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 3058d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 3059badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 3060badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 3061badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3062badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 3063badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 3064ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 3065badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 3066352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 3067352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 3068a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 3069352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 307089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach StringRef ITMask; 30711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 307289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach ProcessorIMod, ITMask); 3073badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 30740c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 30750c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 30760c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 30770c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 30780c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 30790c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 3080ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 3081ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 308289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // Handle the IT instruction ITMask. Convert it to a bitmask. This 308389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // is the mask as it will be for the IT encoding if the conditional 308489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 308589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // where the conditional bit0 is zero, the instruction post-processing 308689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // will adjust the mask accordingly. 308789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (Mnemonic == "it") { 308889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = 8; 308989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = ITMask.size(); i != 0; --i) { 309089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach char pos = ITMask[i - 1]; 309189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (pos != 't' && pos != 'e') { 309289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Parser.EatToEndOfStatement(); 309389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach return Error(NameLoc, "illegal IT instruction mask '" + ITMask + "'"); 309489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 309589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask >>= 1; 309689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if (ITMask[i - 1] == 't') 309789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 8; 309889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 309989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Operands.push_back(ARMOperand::CreateITMask(Mask, NameLoc)); 310089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 310189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach 3102ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 3103ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 31049717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 31053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 31063771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 31073771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 31083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 31093771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 31103771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 31113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 31123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 31131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 31143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 311533c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 311633c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 311733c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 311833c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 3119ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 312033c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 312133c16a27370939de39679245c3dff72383c210bdJim Grosbach } 3122c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 3123c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 3124c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 3125c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 3126c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 3127c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 3128c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 312933c16a27370939de39679245c3dff72383c210bdJim Grosbach 31303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 31313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 31323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 31333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 31343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 313533c16a27370939de39679245c3dff72383c210bdJim Grosbach if (CanAcceptCarrySet) 31363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 31373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 31383771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 31393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 31403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 31413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 31423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 3143badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 3144345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3145a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 3146a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 3147a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 3148a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 3149a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 3150a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3151a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3152345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 31535747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 31545747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 31555747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 3156a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 3157a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 31584d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // For now, we're only parsing Thumb1 (for the most part), so 31594d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // just ignore ".n" qualifiers. We'll use them to restrict 31604d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // matching when we do Thumb2. 31614d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach if (ExtraToken != ".n") 31624d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 31635747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 31645747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 31655747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 31665747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 3167a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 31681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3169cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3170cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3171cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3172a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3173a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 3174b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 3175a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3176a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 31771355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3178cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3179cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3180cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3181a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 318316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3184cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 3185cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 318634e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 3187cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3188146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 318934e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 3190ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3191d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 3192d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 3193d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 3194d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // parse and adjust accordingly before actually matching. Reason number 3195d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // #317 the table driven matcher doesn't fit well with the ARM instruction 3196d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // set. 3197d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (shouldOmitCCOutOperand(Mnemonic, Operands)) { 3198ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3199ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 3200ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 3201ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 3202ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3203cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 3204cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 3205cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 3206cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // a CondCode operand in the list. If we're trying to match the label 3207cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // version, remove the CondCode operand here. 3208cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 3209cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 3210cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3211cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 3212cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 3213cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 3214857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 3215857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 3216857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 3217857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 3218857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 3219857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 3220857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3221857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3222857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3223857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 3224857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 3225857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3226857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 3227857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3228857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3229934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 3230934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 3231934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 3232934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3233934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3234934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3235934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 3236934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 3237934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3238934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 3239934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3240934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3241934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 32429898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 3243ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3244ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3245189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 3246aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3247aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 3248aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 3249aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 3250aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 3251aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 3252aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 3253aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 3254aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 3255aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 3256aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 3257aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 3258aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 3259aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 3260aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 3261aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 3262aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 3263aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3264189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 3265189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 3266189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 3267189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3268189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 32692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 32702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 32712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 3272189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 3273189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3274189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 3275189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3276189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 3277189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 3278189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 3279189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3280189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 328114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 328214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 328314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 328414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 328514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 328614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 328714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 328814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 328914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 329053642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 329153642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 3292189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 3293189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3294189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3295189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 3296189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 329714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 3298189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 3299189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3300189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3301fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 3302fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 3303fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 3304fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 3305fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 3306fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 3307fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 3308fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 330900c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 3310fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 331193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 331293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 331393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 331493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 33157260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 33167260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 33177260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 3318aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3319aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase)) 3320aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 3321aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 332293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 3323aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!listContainsBase && !hasWritebackToken) 332493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 332593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 33267260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach // Likewise, if we should not have writeback, there must not be a '!' 3327aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 33287260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 33297260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 33307260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 333193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 333293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 333393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 33346dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 3335aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3336aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 3337aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3338aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 33396dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 33406dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 33416dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 3342aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3343aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 3344aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3345aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 33466dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 33476dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 33481e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 33491e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 3350f95aaf951b628621c9c74bed6c450b8a52a1ae1eJim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase)) 33511e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 33521e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 33531e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 33541e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 3355189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3356189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3357189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3358189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 3359189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3360f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 3361f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 3362f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3363f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 3364f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 3365f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 3366f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 3367f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 3368f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 3369f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 3370f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 3371f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3372f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3373f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 3374f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 3375f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 3376f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3377f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3378f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 3379f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3380f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 3381f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 3382f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 3383f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 3384f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 3385f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 3386f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 3387f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 3388f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3389f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3390f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 3391f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 3392f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3393f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3394f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 3395f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 3396f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 339789e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 339889e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach // If the immediate is in the range 0-7, we really wanted tADDi3. 339989e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach if (Inst.getOperand(3).getImm() < 8) 340089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 340189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 3402395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 3403395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 3404395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) 3405395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 34063ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 340789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach case ARM::t2IT: { 340889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // The mask bits for all but the first condition are represented as 340989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // the low bit of the condition code value implies 't'. We currently 341089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // always have 1 implies 't', so XOR toggle the bits if the low bit 341189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // of the condition code is zero. The encoding also expects the low 341289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // bit of the condition to be encoded as bit 4 of the mask operand, 341389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach // so mask that in if needed 341489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MCOperand &MO = Inst.getOperand(1); 341589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned Mask = MO.getImm(); 341689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach if ((Inst.getOperand(0).getImm() & 1) == 0) { 341789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach unsigned TZ = CountTrailingZeros_32(Mask); 341889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach assert(Mask && TZ <= 3 && "illegal IT mask value!"); 341989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach for (unsigned i = 3; i != TZ; --i) 342089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask ^= 1 << i; 342189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } else 342289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach Mask |= 0x10; 342389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach MO.setImm(Mask); 342489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach break; 342589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach } 3426f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3427f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 3428f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 342947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 343047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 343147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// API changes, though. Better way? 343247a0d52b69056250a1edaca8b28f705993094542Jim Grosbachnamespace llvm { 343347a0d52b69056250a1edaca8b28f705993094542Jim Grosbachextern MCInstrDesc ARMInsts[]; 343447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 343547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 343647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return ARMInsts[Opcode]; 343747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 343847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 343947a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 344047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 344147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 3442194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 3443194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 344447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 344547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 344647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 344747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 344847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 344947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 345047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 345147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 345247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 345347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 345447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 345547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 345647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 345747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 345847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 345947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 346047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // FIXME: We don't yet do IT blocks, so just always consider it to be 346147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // that we aren't in one until we do. 346247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 346347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 346447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 3465194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 3466194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 3467194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 3468194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 3469194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 3470194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 3471194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 34724ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 3473194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 3474194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 3475194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 347647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 347747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 347847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 3479fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 3480fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 3481fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3482fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 3483fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 3484fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 348519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 3486193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 3487193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 348819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 3489e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 3490189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 3491189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 3492189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (validateInstruction(Inst, Operands)) 3493189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 3494189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3495f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 3496f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 3497f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 3498f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 3499fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 3500fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 3501e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 3502e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 3503e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 3504e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 3505e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 3506e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 3507e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 3508e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 350916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3510e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 3511e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 3512e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 351316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3514e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 3515e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 3516e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 351747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 3518b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 351988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 352088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 352147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 352247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 3523194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 3524194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 3525194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 3526194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 3527fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 352816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3529c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 3530146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 3531fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 3532fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 35331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 3534ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 3535ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 3536ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 35371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 3538515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 35391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 3540515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 35411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 3542515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 35431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 3544515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 35451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 3546ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3547ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3548ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 35491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 3550ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 35511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 3552ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 3553ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 3554ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 3555ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 3556ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3557ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3558aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 3559ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3560ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 3561ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 356216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3563ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 3564ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 3565ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 3566b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3567ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3568ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3569ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3570b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3571ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 3572ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3573ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 35741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 3575515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 35761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 3577515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3578515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3579b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3580515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3581515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 3582515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 3583515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3584515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3585515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3586515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 35871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 3588515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 35891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 35906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 35916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 35926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 35936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 35946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 35956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 35966469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 35976469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 35986469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 35996469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 36006469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 36016469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 36026469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 36036469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3604515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3605515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3606b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3607515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 36086469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 36096469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 36106469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 36116469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 36126469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3613642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 3614642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 3615642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 3616515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3617515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3618515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 36191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 3620515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 36211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 362218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3623515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3624515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 362538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 362658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 3627b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 362858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 36299e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 3630515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3631515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 3632515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3633515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 363418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3635b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3636515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3637515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 3638515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3639515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3640515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3641515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 36421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 3643515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 36441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 364518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3646515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 3647515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 364818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 364958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 3650b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 365158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 3652b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3653515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3654515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 3655515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3656515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 365718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3658b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3659515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 366032869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 3661bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (!isThumb()) { 3662ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3663bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3664bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 366532869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 3666bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (isThumb()) { 3667ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3668bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 3669bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 3670eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 36712a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 3672515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3673515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3674515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 367590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 367690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 36779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 3678ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 367994b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 368094b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 368190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 3682ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 36833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 36840692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 36850692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 36863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 3687