ARMAsmParser.cpp revision 039c2e19c4237fb484315a62e95222ac28640bb7
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" 2194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h" 22ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2394b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 25c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 26fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2775ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 2894b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h" 29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 31345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 34ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 35ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 363a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 37146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 38146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 3916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4094b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 41ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 520d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *applyPrefixToExpr(const MCExpr *E, 589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 60a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 68515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 705f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, unsigned &ProcessorIMod); 711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 72fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 7316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 74ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 75ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 76ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 77ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 78ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 79ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 80ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 8132869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 82ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 83ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 8432869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 85ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 86a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 87a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 890692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 900692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 91a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 92a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 9443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 95f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 9643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 97f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 9843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 998bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1018bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1038bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 104f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 105f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 106f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 107f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 108f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 109f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 110f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 111f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 112c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 113580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 115293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 117ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 1191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 120ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 131189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 132189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 133189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 134189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 135ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 136ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 13794b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 138ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 13932869205052430f45d598fba25ab878d8b29da2dEvan Cheng 140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 141ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 142ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 143ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 1451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 1461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 147189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 1481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 1491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 1501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 1511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 153ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 15416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 15516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1563a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 158a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 159a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 160146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 161762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 163d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 165fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 166cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 167706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 1688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 1697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIndexRegister, 170584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 171a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 1728462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1738d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 1740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 1750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 176e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 17792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 178580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImmediate, 1797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotateImmediate, 180293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach BitfieldDescriptor, 1818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 184762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 18524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 186a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 187a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 188a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1918462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1928462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 193706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 194706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 195706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 196706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 197fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 198fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 199fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 200fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 201a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 202a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 203a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 205584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 206584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 207584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 208584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 214a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2178155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 218cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 219cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 22016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2216a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 222a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 223a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 2257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 2267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 2277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 2287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 2297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned ShiftValue; // shift for OffsetReg. 2307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 231a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 2357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Imm; 2367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 2377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 239580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 241580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 245e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 247af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 24892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 24992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 25092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 25192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 252af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 2537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 2547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 2557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 256293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 257293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 258293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 259293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 260a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 26116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 262146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 263146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 2698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 2708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 2718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 272762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 2738462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 274762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 275d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 276762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 2798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 2800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 2810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 28224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 2838d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 284fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 285fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 286fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 287fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 291706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 292706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 293706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 294762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 296762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 2977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 2987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 2997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 300584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 303a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 304a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 3050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 306580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 307580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 3080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 309e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 310af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 311e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 31292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 313af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 31492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 3157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 3167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 3177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 318293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 319293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 320293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 321762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 322762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 32316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 324762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 325762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 326762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 327762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3308462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3318462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3328462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3338462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 334fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 335fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 336fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 337fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 338fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 339a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 340a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 341a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 342a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 344a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3456aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3467729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 347a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 348a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3495fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3500f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3510f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 35224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3538d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 355cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 356cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 357cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 358cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 359cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 360706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 361706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 362706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 363706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 364706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 365a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 366a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 367a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 368a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 369a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 370584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 371584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 372584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 373584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 374584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 375fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 376fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 3778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 378d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 3793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 3806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 3816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 3826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 3836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 3846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 3856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 3866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 3876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 38883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 38983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 39083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 39183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 39283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 39383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 39483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 39583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 39683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 39783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 39883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 39983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 40083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 40183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 40283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 40383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 4047c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 4057c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (Kind != Immediate) 4067c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 4077c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4087c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 4097c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 4107c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 4117c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 412f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 413f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (Kind != Immediate) 414f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 415f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 416f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 417f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 418f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 419f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 4204a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 4214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (Kind != Immediate) 4224a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 4234a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4244a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 4254a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 4264a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 4274a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 428fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 429fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 430fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 431fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 432fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 433fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 434fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 435fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 436ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 437ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 438ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 439ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 440ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 441ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 442ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 443ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 444ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 445ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 446ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 447ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (Kind != Immediate) 448ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 449ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 450ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 451ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 452ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 453ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 454f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 455f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 456f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 457f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 458f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 459f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 460f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 461f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 462f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 463f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 464f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 465f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 466f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 467f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 468f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 469f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 4706bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 4716bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 4726bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 4736bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4746bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 4756bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 4766bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 4776bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 4786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 4796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 4856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 486c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 487c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Kind != Immediate) 488c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 489c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 490c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 491c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 492c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 493c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 494b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 4958d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 4960f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 4970f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 49814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 499706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 50014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 5017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxReg() const { return Kind == PostIndexRegister; } 502580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isShifterImm() const { return Kind == ShifterImmediate; } 503af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 504af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 5057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach bool isRotImm() const { return Kind == RotateImmediate; } 506293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach bool isBitfield() const { return Kind == BitfieldDescriptor; } 5077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemNoOffset() const { 5087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 509ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 5107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 5117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 512ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 5137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 5147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 515ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 5167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 5177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return true; 5187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 5197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 5227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 523039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 524039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Kind != Immediate) 525039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 526039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 527039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 528039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 529039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 530039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 531039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 5327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 5337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 534ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 5357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 5367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return false; 5377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 5387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0); 5417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 5427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 5437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum) 544ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 545ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 546ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 5477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 5487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 5497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 5507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 5517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftType != ARM_AM::no_shift) 55287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 553505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return true; 554505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 5557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 5567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 557f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 5587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 5597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 562f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 5637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 5647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 565ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 5667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 5677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 5707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 5717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 5727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Immediate) 5737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 5747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 575ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 5767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 5777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 578ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 5797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 580584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 581a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 5823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 5833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 58414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 58514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 58614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 58714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 5883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 5893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 5903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 5913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 5923483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 5938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 594345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 5958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 59604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 59704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 5988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 5998462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 600fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 601fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 602fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 603fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 604fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 605fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 606fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 607fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 608fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 609fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 610d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 611d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 612d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 613d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 614d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 615a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 616a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 617a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 618a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 619a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 620af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 621e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 622af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 623af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 624af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 625e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 626af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 627e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 628e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 629af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 630152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 631af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 632af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 63392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 634af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 63592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 63692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 63792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 638580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 6390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 640580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 641580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 6420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 6430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 64487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 6457729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 6465fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 6475fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 6487729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 6497729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 65087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 65187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 6520f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 6530f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 6540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 6550f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 6560f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 6570f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 6580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 6590f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 6607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 6617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 6627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 6637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 6647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 6657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 666293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 667293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 668293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 669293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 670293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 671293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 672293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 673293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 674293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 675293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 676293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 6773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 6786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 6796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 6806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 6816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 6826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 6836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 6846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 6856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 6866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 68783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 68883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 68983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 69083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 69183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 69283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 6937c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 6947c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 6957c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 6967c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 6977c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 69883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 69983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 70083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 70183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 702f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 703f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 704f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 705f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 706f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 707f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 708f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 709f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 7114a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 7124a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 7134a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 7144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7154a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 7164a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 7174a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 718fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 719fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 720fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 721fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 722fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 723ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 724ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 725ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 726ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 727ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 728ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 729ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 730ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 731ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 732ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 733f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 734f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 735f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 736f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 737f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 738f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 739f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 740f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 741f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 742f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 743f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 744f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 745f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 746f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 7476bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 7486bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 7496bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 7506bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 7516bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 7526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 7533483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 7543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 7553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 75616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 757c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 758c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 759c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 760c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 761c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 762706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 763706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 764706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 765706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 766706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 7677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 7687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 770505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 771505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 7727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 7737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 7747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 7757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetRegNum) { 7767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 7777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 7787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 7797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 7807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 7817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 7827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 7837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 7847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 7857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, Mem.ShiftType); 786ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 7877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 7887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 7897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 790ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 791ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 792039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 793039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 794039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 795039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 796039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 797039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 798039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 799039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 800039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 801039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 802039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 803039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 804039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 805039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 8067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 8077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 8087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 8097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 8107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 8117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 8127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 8137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 8147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 8157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 8167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 8177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 8187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 8197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 8207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 8217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 8227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 8237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 824ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 825ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 8267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 8277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 8287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 8297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 8307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 8317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 83292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 8337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 8347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 8357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 8367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftValue, Mem.ShiftType); 8377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 8387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 8397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 8407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 841d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 8427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 8437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 8447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 8457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 84614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 8473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 8487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 8497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 8527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 8537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 8547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 8557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 856f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 857ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 8597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 8617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.Imm)); 862ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 863ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 864584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 865584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 866584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 867584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 868584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 869a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 870a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 871a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 872a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 874b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 875b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 8763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 8773a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 878345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 879345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 880345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 8813a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 882345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 883345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 884fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 885fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 886fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 887fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 888fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 889fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 890fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 891fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 892fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 893fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 894fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 895fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 896fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 897fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 898fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 899fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 900d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 901d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 902d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 903d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 904d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 905d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 906d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 907d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 9083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 9093a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 910762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 911762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 912762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 913762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 9143a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 915a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 916a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 91750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 9183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 919762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 920762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 921762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 9223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 923a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 924a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 925e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 926e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 927e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 928e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 929e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 930e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 931af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 932af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 933af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 934af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 935e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 936e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 937e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 938e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 939e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 94092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 94192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 94292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 94392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 94492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 945af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 946af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 947af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 94892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 94992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 95092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 95192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 95292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 953580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 9540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 955580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ARMOperand *Op = new ARMOperand(ShifterImmediate); 956580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 957580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 9580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 9590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 9600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 9610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 9620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 9637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 9647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach ARMOperand *Op = new ARMOperand(RotateImmediate); 9657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 9667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 9677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 9687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 9697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 9707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 971293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 972293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 973293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 974293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 975293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 976293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 977293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 978293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 979293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 980293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 9817729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 9825fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 983cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 9840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 9850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 986275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 987275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 9880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 989275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 990275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 9910f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 9920f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9930f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 9945fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 9957729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 99624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 997cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 998cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 999cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 10008d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 10018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 10028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 10033a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 10043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 1005762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1006762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1007762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 10083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1009cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1010cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 10117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 10127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 10137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 10147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 10157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned ShiftValue, 10167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 10173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 10183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 1019762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 10207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetImm = OffsetImm; 10217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetRegNum = OffsetRegNum; 1022762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 10237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.ShiftValue = ShiftValue; 10247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.isNegative = isNegative; 10257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 10267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 10277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 10287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 102916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 10307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, unsigned Imm, 10317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 10327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARMOperand *Op = new ARMOperand(PostIndexRegister); 10337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 10347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.Imm = Imm; 1035762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1036762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 10373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1038a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1039706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1040706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1041706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1042706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1043706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1044706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1045706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1046706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1047a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1048a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1049a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1050a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1051a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1052a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1053a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1054a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1055584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1056584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1057584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1058584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1059584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1060584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1061584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1062584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1063a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1064a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1065a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1066a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1067b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1068fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 1069fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 10706a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1071fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1072d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1073d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1074d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 1075fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1076fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1077fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1078fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1079fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1080fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1081584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1082584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1083584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1084fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1085fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1086fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1087706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1088706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1089706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1090fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 10916ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 10927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << " base:" << Mem.BaseRegNum; 10936ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1094fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 10957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 10967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OS << "post-idx register " 10977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << getAddrOpcStr(ARM_AM::getAM3Op(PostIdxReg.Imm)) 10987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << PostIdxReg.RegNum 10997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << ">"; 11007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 1101a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1102a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1103a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1104a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1105a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1106a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1107a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1108a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1109a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1110fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 111150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1112fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1113580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 1114580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1115580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1116e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1117e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 111892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1119af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1120af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1121af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1122af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1123e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 11240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 112592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 112692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1127af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1128af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1129af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 113092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 113192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 11327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 11337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 11347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 1135293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 1136293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1137293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1138293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 11390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 11400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 11410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 11428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 11438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 11445fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 11455fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 11467729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 11477729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 11487729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 11498d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 11508d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 11518d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 11528d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 11538d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1154fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1155fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1156fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1157fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1158fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 11593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 11603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 11613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 11623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 11633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 11643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 11653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 11663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 116769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 116869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 11691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1170bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1171bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1172bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1173bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 11749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1175e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1176e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 11773a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 11781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 117918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 11807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1181d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 11840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 11850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 11860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 11870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 11880c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 11890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 11900c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 11910c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 11920c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 11930c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 11940c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 11950c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 119669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1197b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1198e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1199e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1200d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 120119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 120219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 120319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 120419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 120519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 12060d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 12070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 12080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 12090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 12100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 12110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 12120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 12130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 12140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 12150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 12160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 12170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 12180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 12190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 12200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 12210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 12220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 122319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 12240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1225e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1226e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1227e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1228e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1229e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1230eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1231e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1232e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1233e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1234e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1235e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1236e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1237e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1238e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1239e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1245e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 124719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 124819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 124919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 125019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1251e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1252e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 125319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 125419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 125519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 125619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1257e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1258e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1259e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1260e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1261e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1262e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1263e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 126419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 126519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1266e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1267e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 12681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1269e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 127019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 127119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 127219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 127319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 127419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 127519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1276e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 127719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 127819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1280e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 128192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 128292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1283af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 12840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 128592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 128692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 128792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 12880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 128919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 12900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 12910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 12920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 129350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 129450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 129550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1296e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1297e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1298e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 129950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 13001355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1301e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 13021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1303e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 130450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1305d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 130650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1308e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1309e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 131050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 131150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1312e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 131399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 131499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 131550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1317a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1318fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1319fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1320fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1321fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1322e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1323e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1324e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1325e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1326e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1327fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1328e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1329e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1330e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1331e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1332e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1333e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1334e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1335e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1336e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1337e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1338e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1339e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1340e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1341e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1342e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1343e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1344fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1345e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1346e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1347e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1348e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1349e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1350e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1351e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1352e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1353e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1354e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1355e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1356e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1357e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1358e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1359e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1360e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 136143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1362fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1363fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1364f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 136543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1366e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1367e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1368e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1369e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1370fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1371e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1372f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1373e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1374e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1375fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1376f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1377fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1378fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 137943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1380fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1381fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1382f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 138343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1384fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1385fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1386fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1387fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1388fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1389fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1390f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1391fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1392fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1393fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1394f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1395e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1396e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1397c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1398c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 139950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 14001355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 140118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1402a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1403e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 140416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 14057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 14067729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 14075fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1408d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 14097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1410e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 14117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1412d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 141318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1414d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1415c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1416c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 141750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1418c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1419e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNum = tryParseRegister(); 1421c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1422c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 142350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1424c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1425d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1426e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1427e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1428e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1429e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1430e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1431e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1432e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1433e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1434e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1435e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1436e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 14377729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 14387729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1439e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1440e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 144118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1442c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1443c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 144450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1445c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1446d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1447e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1448e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 144903f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1450e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 14515fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1452e717610f53e0465cde198536561a3c00ce29d59fBill Wendling RI = Registers.begin(), RE = Registers.end(); 1453e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14547caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned HighRegNum = getARMRegisterNumbering(RI->first); 14558e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 14568e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling 14577caebff83d90a59aa74876ff887e822387f479e0Bill Wendling DenseMap<unsigned, bool> RegMap; 14587caebff83d90a59aa74876ff887e822387f479e0Bill Wendling RegMap[HighRegNum] = true; 14597caebff83d90a59aa74876ff887e822387f479e0Bill Wendling 1460e717610f53e0465cde198536561a3c00ce29d59fBill Wendling for (++RI; RI != RE; ++RI) { 14617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling const std::pair<unsigned, SMLoc> &RegInfo = *RI; 14627caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1463e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14648e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1465e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 146650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1467e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1468e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14698e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1470e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1471e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1472e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14738e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling RegMap[Reg] = true; 14748e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1475e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1476e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 147750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 147850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1479d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1480d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 148143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1482f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 148343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1484706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1485706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1486706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1487706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1488706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1489706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1490706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1491706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1492032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 1493706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1494032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 1495706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1496706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1497032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 1498706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1499032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 1500706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1501706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1502706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1503706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1504706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1505f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1506706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1507706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1508706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1509f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1510706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1511706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 151243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1513a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 151443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1519a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1524a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1527a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1528a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1529a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1530a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1532a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1533a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1534a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1535a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1536a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1537a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1538a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1539584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1540584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 154143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 154343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1544584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1545584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1549584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1550584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1551584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1552b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1553584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1554584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1555584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1556584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1557584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1558584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1559584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1560584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1561584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1562584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1563b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 1564584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1565584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1566584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1567584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 15684b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1569584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1570584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1571584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1572584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 15734b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1574584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 157556926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 157656926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1577584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1578584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1579584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1580584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1581584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1582584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1583584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1584584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1585584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1586584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1587584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1588584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1589584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1590584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1591584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1592584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1593584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1594584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1595584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1596584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1597584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1600584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1601584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1603584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1604584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1605a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1606a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1607f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1608f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1609f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 1610f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1611f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1612f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1613f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1614f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1615f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 1616f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 1617f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 1618f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 1619f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1620f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1621f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1622f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 1623f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1624f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 1625f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1626f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1627f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1628f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1629f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 1630f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1631f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 1632f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 1633f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1634f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 1635f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1636f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1637f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1638f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 1639f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 1640f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1641f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1642f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1643f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 1644f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 1645f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1646f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1648f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1649f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1650f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 1651f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 1652f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1653c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1654c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1655c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1656c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 1657c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1658c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1659c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1660c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1661c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 1662c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 1663c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 1664c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 1665c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 1666c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1667c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 1668c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1669c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1670c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1671c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1672c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 1673c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 1674c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 1675c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 1676c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1677580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1678580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 1679580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 1680580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 1681580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 1682580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1683580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1684580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 1685580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 1686580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1687580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1688580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1689580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1690580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 1691580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 1692580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 1693580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 1694580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 1695580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 1696580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 1697580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1698580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1699580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1700580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 1701580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1702580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 1703580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1704580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1705580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1706580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1707580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 1708580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1709580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 1710580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 1711580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1712580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 1713580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1714580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1715580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1716580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 1717580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 1718580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1719580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1720580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1721580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 1722580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 1723580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1724580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 1725580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 1726580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1727580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1728580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // asr #32 encoded as asr #0. 1729580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 1730580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 1731580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1732580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 1733580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 1734580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1735580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1736580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1737580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1738580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 1739580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 1740580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1741580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 1742580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 1743580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 17447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 17457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 17467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 17477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 17487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 17497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 17507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 17517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 17527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 17537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 17547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 17557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 17567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") { 17577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 17587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 17597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 17607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 17617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 17627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 17637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 17647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 17657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 17667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 17677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 17687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 17697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 17707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 17717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 17727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 17737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 17747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 17757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 17767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 17777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 17787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 17797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 17807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 17817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 17827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 17837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 17847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 17857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 17867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 17877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 17887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 17897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 17907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 17917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 17927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 17937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 17947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 17957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1796293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1797293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1798293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 1799293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 1800293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1801293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1802293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1803293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1804293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1805293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1806293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 1807293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 1808293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 1809293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 1810293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1811293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1812293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 1813293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 1814293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 1815293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1816293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1817293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1818293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 1819293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 1820293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 1821293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 1822293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1823293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1824293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 1825293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1826293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 1827293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 1828293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 1829293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1830293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1831293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1832293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1833293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1834293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1835293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1836293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1837293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1838293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 1839293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 1840293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 1841293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1842293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1843293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 1844293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 1845293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 1846293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1847293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1848293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1849293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 1850293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 1851293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 1852293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 1853293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1854293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1855293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 1856293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1857293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 1858293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1859293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 1860293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 1861293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 18627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 18637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 18647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 18657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // postidx_reg := '+' register 18667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // | '-' register 18677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // | register 18687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 18697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 18707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 18717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 18727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 18737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 18747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 18757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Imm = ARM_AM::getAM3Opc(ARM_AM::add, 0); 18767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 18777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 18787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 18797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 18807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 18817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 18827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = ARM_AM::getAM3Opc(ARM_AM::sub, 0); 18837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 18847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 18857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 18867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 18877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 18887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 18897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 18907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 18917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 18927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 18937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 18947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 18957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, Imm, S, E)); 18967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 18977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 18987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 18997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 19001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1901ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1902ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1903ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 19041355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1905ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1906ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1907ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1908ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1909ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1910ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 19117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 1912ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1913ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1914ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1915ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 19161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1917ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1918ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1919ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 19201355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1921ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1922ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1923ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 19247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(0 && "cvtStWriteBackRegAddrMode2 not implemented yet!"); 19257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 19267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 19277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 19287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 19297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 19307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 19317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 19327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 19337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 19347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 1935ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 19367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 19377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 19387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 19397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 19407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 19417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 19427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 1943ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1944ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1945ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1946ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 19477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 1948ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1949ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1950ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 19517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 19527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 19537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 1954aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1955ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1956ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 19577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 19587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 19597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 19607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 19617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 19627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 19637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 19647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 1965aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 19667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 19677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 19687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 19697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 19707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 19717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 19727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 19737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 19747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 19757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 19767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 19777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 19787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 19797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 19807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 1981ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1982ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1983ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1984ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 19857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 1986ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1987ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1988ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 19897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 19907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1991ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1992ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 19937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 1994ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 19957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 19967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 19977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 19987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 19997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2000ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2001ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2002ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2003ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 2004e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 20059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 200650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 20077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2008762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 200918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 2010a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 2011762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2012b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 2013a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 201418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 20151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 20167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 20177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 2018a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 20190571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 20200571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 20210571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 20227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 20230571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 20247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 2025762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 2026b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 2027a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 20287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 20297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, false, S, E)); 203003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 20317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 20327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 203350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 20347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 20357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 203650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 20377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If we have a '#' it's an immediate offset, else assume it's a register 20387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 20397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 20407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 20417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 204250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 20437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // FIXME: Special case #-0 so we can correctly set the U bit. 2044e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 20457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 20467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 20477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 204805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 20497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 20507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 20517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 20527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 20537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 20547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 20557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 20567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 20577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 20587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 20597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 20607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 206105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 20627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 20637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 20647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 20657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::no_shift, 0, false, S,E)); 2066a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 20677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 20687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 20697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 20707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 20717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 2072762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 20737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 20747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 20759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 2076d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 20777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 20787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 20797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 20807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 20817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 20827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 20837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 20847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 20857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 20869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 20877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 20887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 20897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 20907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 20917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 20927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 20937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 20947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned ShiftValue = 0; 20957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 20967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 20977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftValue)) 20987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 20999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 210016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 21017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 21027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 21037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 21047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 21057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 21067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 21087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ShiftType, ShiftValue, isNegative, 21097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 21107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 21139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 21149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 21159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 21167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 2117a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 2118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 21197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 21207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 21217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 21227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 212318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2124a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2125a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 212638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 2127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 21280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 2129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 21300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 2131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 21320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 2133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 21340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 2135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 21360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 2137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 21387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 2139b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 2140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 21417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 21427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 21437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 21447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 21457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 21467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 21477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 21487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 21497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 21509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 21517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 21527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 21537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 21547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 21557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 21567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 21577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 21587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 21597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 21607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 21617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 21627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 21637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 21647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 21657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 21667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 2167a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2168a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 2169a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 21719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 21729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 21731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2174fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 2175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 2176fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2177fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 2178fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 2179f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2180f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 2181fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 2182f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 2183f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 2184f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 2185f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 2186f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 2187fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2188a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 2189146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 2190146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 219150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 219219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 21931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 219450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 21950d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 219619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 21970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 219819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 219919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 2200e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 2202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 220319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 220467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 220567b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 2206515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 2207515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 2208515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 2209762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2210515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 221150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2212762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 221350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 221450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 221550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 2216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 22171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 2218d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 22191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 2220d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 2221079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 2222079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2223762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2224b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2225515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 2226515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 222750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2228762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 222950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 223050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 22319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 22329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 22337597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 22347597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 22357597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 22361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 22379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 22389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22397597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 22407597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 22419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 22429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22437597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 22447597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 22459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 22467597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 22479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 22489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 2249a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2251a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 22521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 22537597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 22541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 22557597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 22569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 22588a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 22599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 22609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 22629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 22639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 22649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 22659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 22679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 22687597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 22699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 22707597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 22719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 22729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 22739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 22749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 22759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 22769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 22789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 22799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 22809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 22819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 22829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 22839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 22849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 22861355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E, 22879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 22889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 22899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 22909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 22919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 22929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 22949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 22959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 22969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 22979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 22989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 23009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 23019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 23029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 23039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 23049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 23059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 23069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 23079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 23089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 23099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 23109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 23119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 23129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 23131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant); 23149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 23159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 23169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 23179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 23189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 23199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 23209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 23219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 23229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 23239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 23249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 23259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 2326352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 2327352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 2328352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 2329badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 23301355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 23315f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 23325f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 23335f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &ProcessorIMod) { 2334352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 2335352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 2336a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 2337352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2338badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 2339352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 2340352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 23415f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 23425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 23435f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 23445f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 23455f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 23465f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 23475f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 23485f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2349352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2350badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 23513f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 23523f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 2353ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 235471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 235549f2ceddd25c75373f8a39fa25e8b9db33bcdaccJim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls") { 23563f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 23573f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 23583f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 23593f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 23603f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 23613f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 23623f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 23633f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 23643f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 23653f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 23663f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 23673f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 23683f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 23693f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 23703f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 23713f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 23723f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 23733f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 23743f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 23753f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 23763f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 23773f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 23783f00e317064560ad11168d22030416d853829f6eJim Grosbach } 237952925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 2380345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2381352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 2382352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 2383352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 2384352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 23855f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 23865f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 23875f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 2388e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 2389e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 2390352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2391352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 2392352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 2393352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2394a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 2395a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 2396a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 2397a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 2398a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 2399a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2400a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 2401a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 2402a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2403a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 2404a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2405a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 2406a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2407a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2408a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2409352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2410352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 24113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 24123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 24133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 24143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 24153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 2416fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 24171355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2418fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 2419eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2420eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2421eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2422eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2423be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2424eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2425eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 2426be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "eor" || Mnemonic == "smlal" || 2427ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 2428eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 2429eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 2430eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 2431eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 24323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 2433eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2434eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2435eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2436eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 24375f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2438c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Mnemonic == "setend" || 243948c693ff564c422153733424ab845106161430acJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) || 2440e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) 2441e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach && !isThumb()) || 24425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 24433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 24443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 24453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 24463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 2447fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 2448ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 2449fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 245063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2451fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 2452badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 2453badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2454badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 2455badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2456badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2457badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 2458badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 2459ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 2460badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2461352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 2462352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 2463a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 2464352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 24651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2466c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach ProcessorIMod); 2467badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2468ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2469ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2470ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 2471ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 24729717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 24733771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 24743771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 24753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 24763771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 24773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 24783771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 24793771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 24803771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 24811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 24823771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 248333c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 248433c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 248533c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 248633c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 2487ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 248833c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 248933c16a27370939de39679245c3dff72383c210bdJim Grosbach } 2490c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 2491c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 2492c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 2493c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 2494c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 2495c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 2496c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 249733c16a27370939de39679245c3dff72383c210bdJim Grosbach 24983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 24993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 25003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 25013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 25023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 250333c16a27370939de39679245c3dff72383c210bdJim Grosbach if (CanAcceptCarrySet) 25043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 25053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 25063771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 25073771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 25083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 25093771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 25103771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 2511badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 2512345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2513a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 2514a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 2515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 2516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 2517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 2518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 2519a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 2520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 2521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 2523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2524a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2525345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 25265747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 25275747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 25285747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 2529a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 2530a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 25325747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 25335747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 25345747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 25355747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 2536a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 25371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 2538cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2539cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2540cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 2543b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 2544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2545a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 25461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 2547cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2548cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2549cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2550a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2551a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 255216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2553cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2554cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 255534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 2556cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2557146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 255834e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 2559ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2560ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2561ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2562ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 2563ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 2564ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // operand if that's the instruction we're trying to match. 2565ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // 2566ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // We do this post-processing of the explicit operands rather than just 2567ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // conditionally adding the cc_out in the first place because we need 2568ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // to check the type of the parsed immediate operand. 2569ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Mnemonic == "mov" && Operands.size() > 4 && 2570ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2571731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2572731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) { 2573ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2574ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 2575ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 2576ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 2577ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2578cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 2579cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 2580cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 2581cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // a CondCode operand in the list. If we're trying to match the label 2582cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // version, remove the CondCode operand here. 2583cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 2584cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 2585cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2586cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 2587cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 2588cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 25899898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 2590ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2591ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2592189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 2593189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 2594189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 2595189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 2596189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2597189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 2598189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 2599189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 2600189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 2601189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2602189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 2603189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 2604189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 2605189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2606189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 2607189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 2608189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 2609189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2610189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 2611189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 2612189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[4]->getStartLoc(), 2613189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 2614189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2615189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 2616fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 2617fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 2618fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 2619fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 2620fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 2621fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 2622fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 2623fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 2624fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 2625189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 2626189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 2627189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2628189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 2629189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 2630fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 2631fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 2632fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2633fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 2634fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 2635fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 26365a18700470f0831b9b2af78862672561dd980345Jim Grosbach MatchResultTy MatchResult; 2637193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2638193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 2639e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 2640189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 2641189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 2642189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (validateInstruction(Inst, Operands)) 2643189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 2644189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 2645fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 2646fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 2647e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 2648e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2649e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 2650e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 2651e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 2652e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 2653e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 2654e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 265516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2656e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2657e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2658e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 265916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2660e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 2661e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 2662e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 2663e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 2664b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 2665b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 2666fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 266716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2668c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 2669146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 2670fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 2671fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 26721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 2673ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2674ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 2675ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 26761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 2677515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 26781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 2679515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 26801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 2681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 26821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 2683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 26841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 2685ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2686ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2687ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 26881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 2689ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 26901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 2691ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 2692ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 2693ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 2694ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 2695ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2696ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2697aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2698ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2699ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 2700ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 270116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2702ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 2703ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 2704ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 2705b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2706ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2707ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2708ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2709b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2710ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 2711ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2712ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 27131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 2714515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 27151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 2716515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2717515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2718b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2719515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2720515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 2721515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 2722515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2723515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2724515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2725515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 27261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 2727515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 27281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 27296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 27306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 27316469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 27326469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 27336469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 27346469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 27356469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 27366469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 27376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 27386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 27396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 27406469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 27416469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 27426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2743515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2744515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2745b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2746515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 27476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 27486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 27496469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 27506469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 27516469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2752642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 2753642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2754642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 2755515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2756515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2757515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 27581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 2759515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 27601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 276118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2762515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2763515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 276438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 276558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 2766b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 276758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 27689e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 2769515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2770515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 2771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2772515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 277318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2774b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2775515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2776515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 2777515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2778515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2779515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2780515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 27811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 2782515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 27831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 278418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2785515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 2786515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 278718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 278858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 2789b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 279058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 2791b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2792515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2793515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 2794515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 279618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2797b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2798515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 279932869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 2800bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (!isThumb()) { 2801ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 2802bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 2803bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 280432869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 2805bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (isThumb()) { 2806ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 2807bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2808bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 2809eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 28102a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 2811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2812515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2813515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 281490b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 281590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 28169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 2817ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 281894b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 281994b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 282090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 2821ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 28223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 28230692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 28240692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 28253483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 2826