ARMAsmParser.cpp revision 3912b73c74dc9c928228504e9a23c577b57c4e12
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 } 8147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 8247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 8347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 8432869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 85ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 86ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 8732869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 88ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 89a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 90a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 920692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 930692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 94a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 95a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 96a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 9743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 98f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 9943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 100f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1028bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1048bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1068bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 107f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 108f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 109f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 110f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 111f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 112f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 113f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 114f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 115c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 116580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 118293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 120251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 121ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 1231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 124ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 125548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 126548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 128ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1297b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1307b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 14114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 14214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 143623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 144623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 145189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 146189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 147189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 148f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach void processInstruction(MCInst &Inst, 149f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 150d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 151d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 152189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 153ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 15447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 15547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY 15647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 15747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 158ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 15994b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 160ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 16132869205052430f45d598fba25ab878d8b29da2dEvan Cheng 162ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 163ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 164ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 165ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 1671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 1681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 169189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 1701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 1711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 17247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 17347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 1741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 1751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 177ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 17816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 17916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1803a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1813a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 184146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 185762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 187d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 188fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 189fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 190cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 1928462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 1937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIndexRegister, 194584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 195a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 1968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1978d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 1980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 1990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 200e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 20192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 202580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImmediate, 2037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotateImmediate, 204293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach BitfieldDescriptor, 2058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 207a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 208762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 20924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2168462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 217706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 218706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 219706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 220706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 221fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 222fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 223fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 224fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 225a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 226a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 227a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 228a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 229584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 230584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 231584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 232584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 233a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 235a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 236a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 237a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 238a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 239a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 240a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2418155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 242cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 243cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 24416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2456a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 246a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 2497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 2507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 2517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 2527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 2530d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm; // shift for OffsetReg. 2547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 255a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 259f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 260f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 261f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 2627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 2637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 265580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 266e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 267580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 268e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 269e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 270e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 271e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 272e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 273af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 27492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 27592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 27692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 27792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 278af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 2797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 2807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 2817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 282293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 283293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 284293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 285293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 286a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 28716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 288146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 289146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 293762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 294762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 2958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 2968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 2978462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 2998462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 301d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 304762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3058d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 3060f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 3070f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 30824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 3098d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 310fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 311fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 312fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 313fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 314762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 315762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 316762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 317706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 318706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 319706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 320762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 321762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 322762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 3247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 3257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 3310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 332580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 333580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 3340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 335e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 336af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 337e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 33892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 339af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 34092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 3417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 3427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 3437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 344293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 345293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 346293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 347762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 348762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 34916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 350762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 351762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 352762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 353762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 354a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3558462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3568462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3578462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3588462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 360fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 361fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 362fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 363fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 364fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 365a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 366a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 367a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 368a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 369a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 370a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3716aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3727729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 373a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 374a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3755fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3760f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3770f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 37824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3808d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 381cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 382cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 383cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 384cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 385cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 386706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 387706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 388706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 389706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 390706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 391a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 392a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 393a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 394a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 395a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 396584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 397584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 398584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 399584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 400584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 401fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 402fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 4038462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 404d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 4053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 4066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 4076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4106b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4126b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 4136b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 41483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 41583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 41683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 41783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 41883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 41983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 42083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 42183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 42283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 42383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 42483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 42583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 42683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 42783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 42883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 42983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 4307c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 4317c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (Kind != Immediate) 4327c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 4337c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4347c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 4357c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 4367c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 4377c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 438f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 439f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (Kind != Immediate) 440f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 441f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 442f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 443f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 444f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 445f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 4464a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 4474a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (Kind != Immediate) 4484a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 4494a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4504a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 4514a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 4524a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 4534a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 454fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 455fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 456fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 457fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 458fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 459fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 460fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 461fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 462ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 463ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 464ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 465ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 466ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 467ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 468ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 469ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 470ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 471ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 472ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 473ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (Kind != Immediate) 474ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 475ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 476ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 477ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 478ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 479ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 480f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 481f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 482f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 483f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 484f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 485f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 486f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 487f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 488f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 489f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 490f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 491f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 492f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 493f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 494f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 495f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 4966bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 4976bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 4986bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 4996bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5006bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 5016bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 5026bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 5036bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 5046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 5056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 5066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5106b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 5116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 512c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 513c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Kind != Immediate) 514c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 515c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 516c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 517c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 518c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 519c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 520b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 5218d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 5220f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 5230f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 52414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 525706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 52614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 527580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isShifterImm() const { return Kind == ShifterImmediate; } 528af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 529af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 5307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach bool isRotImm() const { return Kind == RotateImmediate; } 531293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach bool isBitfield() const { return Kind == BitfieldDescriptor; } 532f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; } 533f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 534f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 535f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 5367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemNoOffset() const { 5377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 538ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 5397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 5407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 541ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 5427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 5437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 544ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 5457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 5467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return true; 5477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 5487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 5517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 552039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 553039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Kind != Immediate) 554039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 555039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 556039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 557039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 558039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 559039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 560039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 5612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 5622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Memory) 5632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 5642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 5652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.ShiftType != ARM_AM::no_shift) return false; 5662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 5672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.OffsetRegNum) return true; 5682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 5692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetImm) return true; 5702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 5722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 5732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 5742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Immediate && Kind != PostIndexRegister) 5752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 5762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) 5772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 5782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 5792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 5812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 582251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 583251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 5842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 5857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 5867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 587ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 5887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 5897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return false; 5907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 5917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0); 5947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 5957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 5967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum) 597ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 598ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 599ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 6007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 6017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 6027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 6037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 6047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftType != ARM_AM::no_shift) 60587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 606505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return true; 607505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 6087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 6097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 610f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 6117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 6127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 615f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 6167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 61709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 61809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 61909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 62009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) 62109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 62209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 6237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 624ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 6257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 6267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 6297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 6307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 6317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Immediate) 6327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 6337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 634ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 6357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 6367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 637ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 6387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 639584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 640a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 6413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 6423483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 64314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 64414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 64514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 64614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 6473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 6483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 6493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 6503483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 6513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 6528462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 653345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 6548462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 65504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 65604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 6578462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 6588462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 659fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 660fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 661fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 662fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 663fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 664fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 665fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 666fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 667fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 668fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 669d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 670d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 671d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 672d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 673d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 674a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 675a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 676a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 677a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 678a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 679af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 680e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 681af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 682af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 683af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 684e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 685af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 686e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 687e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 688af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 689152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 690af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 691af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 69292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 693af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 69492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 69592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 69692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 697580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 6980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 699580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 700580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 7010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 7020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 70387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 7047729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 7055fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 7065fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 7077729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 7087729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 70987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 71087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 7110f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 7120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 7130f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 7140f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 7160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 7170f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 7180f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 7207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 7227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 7237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 7247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 725293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 726293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 727293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 728293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 729293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 730293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 731293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 732293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 733293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 734293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 735293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 7363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 7376b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7386b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 7396b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 7406b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 7416b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 7426b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7436b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 7446b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 7456b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 74683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 74783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 74883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 74983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 75083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 75183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 7527c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7537c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 7547c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 7557c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 7567c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 75783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 75883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 75983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 76083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 761f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 762f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 763f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 764f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 765f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 766f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 767f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 768f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 7694a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 7704a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 7714a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 7724a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 7734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7744a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 7754a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 7764a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 777fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 778fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 779fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 780fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 781fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 782ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 783ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 784ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 785ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 786ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 787ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 788ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 789ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 790ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 791ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 792f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 793f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 794f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 795f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 796f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 797f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 798f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 799f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 800f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 801f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 802f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 803f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 804f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 805f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 8066bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 8076bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 8086bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 8096bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 8106bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 8116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 8123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 8133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 8143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 81516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 816c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 817c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 818c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 819c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 820c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 821706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 822706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 823706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 824706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 825706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 8267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 8277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 829505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 830505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 8317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 8327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 8337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 8347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetRegNum) { 8357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 8367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 8377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 8387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 8397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 8407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 8417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 8427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 8437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 844dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 845ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 8467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 8477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 8487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 849ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 850ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 851039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 852039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 853039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 854039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 855039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 856039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 857039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 858039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 859039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 860039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 861039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 862039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 863039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 864039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 8652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 8662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 8672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 8682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetRegNum) { 8692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 8702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 8712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 8722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 8732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 8742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 8752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 8762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 8772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 8782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 8792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 8802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 8812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 8822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 8832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 8842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 8852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 8862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) { 8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 8882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 8902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 891251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 8942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 8952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 8962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 8972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 8982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 8992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 9002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 901251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 9022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 9032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 9077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 9097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 9107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 9127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 9137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 9147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 9157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 9187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 9197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 9207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 924ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 925ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 9267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 9277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 92809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 92909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate) { 93009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 93109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 93209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 93309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 93409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 93509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 9367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 94092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 9417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 9427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 9440d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 9457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 9477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 949d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 9507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 9517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 95414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 9553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 9577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 9607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 9617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 9627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 9637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 964f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 965ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 9667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 9677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 969f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 970f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 971f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 972f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 973f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 974f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 975f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 976f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 977f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 978f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 979f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 980f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 981ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 982ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 983584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 984584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 985584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 986584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 987584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 988a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 989a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 990a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 991a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 992a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 993b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 994b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 9953a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 9963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 997345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 998345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 999345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 10003a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1001345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1002345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1003fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 1004fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 1005fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1006fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1007fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1008fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1009fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1010fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1011fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 1012fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 1013fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1014fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1015fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1016fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1017fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1018fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1019d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 1020d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 1021d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1022d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1023d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1024d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1025d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1026d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 10273a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 10283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 1029762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1030762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1031762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1032762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 10333a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1034a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1035a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 103650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 10373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 1038762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1039762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1040762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 10413a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1042a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1043a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1044e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1045e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1046e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1047e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1048e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 1049e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 1050af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1051af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1052af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1053af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1054e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 105992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 106092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 106192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 106292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 106392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 1064af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1065af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1066af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 106792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 106892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 106992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 107092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 107192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1072580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 10730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 1074580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ARMOperand *Op = new ARMOperand(ShifterImmediate); 1075580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1076580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 10770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 10780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 10790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 10800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 10810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 10837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach ARMOperand *Op = new ARMOperand(RotateImmediate); 10847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 10857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 10867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 10877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 10887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 10897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1090293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1091293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 1092293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 1093293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1094293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1095293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1096293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1097293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1098293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1099293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 11007729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 11015fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1102cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 11030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 11040f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1105275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 1106275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 11070f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 1108275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 1109275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 11100f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 11110f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 11120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 11135fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 11147729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 111524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1116cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1117cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1118cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 11198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 11208d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 11218d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 11223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 11233a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 1124762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1125762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1126762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 11273a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1128cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1129cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 11307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 11317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 11327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 11337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 11340d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 11357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 11363a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 11373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 1138762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 11397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetImm = OffsetImm; 11407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetRegNum = OffsetRegNum; 1141762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 11420d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Op->Mem.ShiftImm = ShiftImm; 11437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.isNegative = isNegative; 11447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 11457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 11467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 11477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 114816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1149f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1150f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1151f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 11527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 11537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARMOperand *Op = new ARMOperand(PostIndexRegister); 11547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1155f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1156f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1157f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1158762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 11603a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1161a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1162706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1163706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1164706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1165706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1166706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1167706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1168706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1169706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1170a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1171a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1172a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1173a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1174a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1175a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1176a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1177a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1178584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1179584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1180584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1181584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1182584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1183584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1184584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1185584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1186a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1187a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1188a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1189a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1190b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1191fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 1192fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 11936a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1194fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1195d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1196d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1197d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 1198fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1199fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1200fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1201fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1202fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1203fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1204584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1205584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1206584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1207fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1208fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1209fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1210706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1211706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1212706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1213fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 12146ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 12157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << " base:" << Mem.BaseRegNum; 12166ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1217fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 12187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 1219f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1220f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1221f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1222f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1223f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1224f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 12257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 1226a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1227a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1228a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1229a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1230a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1231a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1232a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1233a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1234a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1235fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 123650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1237fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1238580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 1239580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1240580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 124392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1244af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1245af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1246af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1247af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1248e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 12490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 125092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 125192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1252af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1253af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1254af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 125592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 125692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 12577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 12587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 12597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 1260293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 1261293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1262293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1263293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 12640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 12650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 12660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 12678d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 12688d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 12695fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 12705fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 12717729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 12727729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 12737729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 12748d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 12758d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 12768d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 12778d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 12788d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1279fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1280fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1281fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1282fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1283fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 12843483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 12863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 12873483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 12893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 12913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 129269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 129369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 12941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1295bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1296bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1297bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1298bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 12999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1300e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1301e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 13023a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 13031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 130418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 13057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1306d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 13090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 13100c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 13110c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 13120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 13130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 13140c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 13150c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 13160c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 13170c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 13180c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 13190c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 13200c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 132169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1322b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1323e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1324e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1325d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 132619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 132719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 132819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 132919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 133019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 13310d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 13320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 13330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 13340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 13350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 13360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 13370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 13380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 13390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 13400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 13410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 13420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 13430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 13440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 13450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 13460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 13470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 134819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 13490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1350e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1351e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1352e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1353e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1354e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1355eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1356e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1357e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1358e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1359e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1360e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1361e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1362e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1363e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1364e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1365e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1366e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1367e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1368e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1369e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1370e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1371e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 137219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 137319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 137419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 137519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1376e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1377e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 137819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 137919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 138019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 138119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1383e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1385e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1386e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1387e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1388e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 138919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 139019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1391e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1392e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 13931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1394e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 139519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 139619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 139719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 139819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 139919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 140019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1401e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 140219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 140319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1404e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1405e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 140692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 140792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1408af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 14090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 141092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 141192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 141292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 14130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 141419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 14150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 14160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 141850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 141950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 142050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1421e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1422e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1423e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 142450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 14251355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1426e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 14271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1428e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 142950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1430d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 143150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1432a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1433e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1434e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 143550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 143650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1437e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 143899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 143999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1442a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1443fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1444fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1445fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1446fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1447e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1448e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1449e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1450e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1451e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1452fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1453e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1454e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1455e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1456e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1457e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1458e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1459e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1460e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1461e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1462e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1463e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1464e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1465e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1466e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1467e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1468e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1469fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1470e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1471e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1472e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1473e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1474e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1475e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1476e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1477e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1478e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1479e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1480e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1481e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1482e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1483e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1484e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1485e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 148643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1487fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1488fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1489f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 149043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1491e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1492e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1493e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1494e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1495fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1496e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1497f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1498e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1499e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1500fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1501f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1502fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1503fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 150443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1505fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1506fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1507f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 150843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1509fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1510fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1511fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1512fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1513fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1514fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1515f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1516fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1517fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1518fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1519f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1520e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1521e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1522c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1523c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 152450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 15251355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 152618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1527a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1528e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 152916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 15307729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 15317729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 15325fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1533d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 15347729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1535e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 15367729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1537d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 153818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1539d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1540c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1541c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 154250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1543c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1544e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNum = tryParseRegister(); 1546c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1547c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 154850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1549c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1550d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1551e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1552e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1553e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1554e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1555e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1556e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1557e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1558e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1559e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1560e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1561e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 15627729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 15637729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1564e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1565e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 156618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1567c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1568c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 156950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1570c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1571d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1572e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1573e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 157403f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1575e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 15765fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1577e717610f53e0465cde198536561a3c00ce29d59fBill Wendling RI = Registers.begin(), RE = Registers.end(); 1578e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15797caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned HighRegNum = getARMRegisterNumbering(RI->first); 15808e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 15818e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling 15827caebff83d90a59aa74876ff887e822387f479e0Bill Wendling DenseMap<unsigned, bool> RegMap; 15837caebff83d90a59aa74876ff887e822387f479e0Bill Wendling RegMap[HighRegNum] = true; 15847caebff83d90a59aa74876ff887e822387f479e0Bill Wendling 1585e717610f53e0465cde198536561a3c00ce29d59fBill Wendling for (++RI; RI != RE; ++RI) { 15867729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling const std::pair<unsigned, SMLoc> &RegInfo = *RI; 15877caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1588e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15898e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1590e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 159150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1592e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1593e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15948e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1595e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1596e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1597e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15988e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling RegMap[Reg] = true; 15998e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1600e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1601e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 160250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 160350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1604d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1605d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 160643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1607f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 160843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1609706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1610706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1611706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1612706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1613706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1614706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1615706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1616706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1617032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 1618706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1619032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 1620706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1621706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1622032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 1623706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1624032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 1625706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1626706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1627706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1628706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1629706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1630f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1631706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1632706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1633706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1634f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1635706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1636706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 163743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1638a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 163943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1640a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1641a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1642a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1643a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1644a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1645a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1646a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1647a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1648a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1649a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1650a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1651a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1652a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1653a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1654a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1655a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1656a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1657a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1658a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1659a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1660a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1661a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1662a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1663a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1664584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1665584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 166643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1667584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 166843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1669584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1670584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1671584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1672584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1673584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1674584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1675584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1676584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1677b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1678584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1679584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1680584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1681584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1682584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1683584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1684584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1685584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1686584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1687584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1688b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 1689584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1690584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1691584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1692584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 16934b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1694584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1695584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1696584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1697584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 16984b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1699584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 170056926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 170156926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1702584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1703584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1704584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1705584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1706584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1707584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1708584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1709584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1710584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1711584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1712584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1713584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1714584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1715584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1716584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1717584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1718584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1719584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1720584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1721584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1722584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1723584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1724584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1725584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1726584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1727584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1728584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1729584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1730a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1731a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1732f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1733f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1734f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 1735f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1736f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1737f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1738f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1739f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1740f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 1741f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 1742f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 1743f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 1744f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1745f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1746f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1747f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 1748f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1749f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 1750f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1751f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1752f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1753f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1754f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 1755f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1756f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 1757f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 1758f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1759f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 1760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1761f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 1764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 1765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1766f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1767f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1768f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 1769f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 1770f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1771f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1772f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1773f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1774f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1775f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 1776f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 1777f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1778c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1779c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1780c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1781c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 1782c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1783c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1784c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1785c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1786c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 1787c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 1788c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 1789c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 1790c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 1791c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1792c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 1793c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1794c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1795c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1796c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1797c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 1798c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 1799c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 1800c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 1801c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1802580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1803580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 1804580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 1805580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 1806580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 1807580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1808580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1809580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 1810580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 1811580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1812580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1813580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1814580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1815580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 1816580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 1817580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 1818580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 1819580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 1820580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 1821580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 1822580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1823580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1824580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1825580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 1826580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1827580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 1828580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1829580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1830580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1831580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1832580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 1833580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1834580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 1835580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 1836580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1837580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 1838580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1839580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1840580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1841580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 1842580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 1843580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1844580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1845580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1846580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 1847580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 1848580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1849580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 1850580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 1851580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1852580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1853580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // asr #32 encoded as asr #0. 1854580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 1855580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 1856580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1857580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 1858580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 1859580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1860580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1861580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1862580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1863580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 1864580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 1865580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1866580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 1867580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 1868580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 18697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 18707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 18717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 18727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 18737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 18747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 18757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 18767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 18777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 18787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 18797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 18807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 18817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") { 18827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 18837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 18847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 18857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 18867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 18877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 18887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 18897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 18907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 18917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 18927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 18937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 18947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 18957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 18967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 18977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 18987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 18997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 19017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 19027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 19037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 19077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 19087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 19097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 19107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 19117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 19127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 19167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 19177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 19197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 19207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1921293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1922293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1923293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 1924293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 1925293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1926293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1927293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1928293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1929293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1930293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1931293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 1932293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 1933293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 1934293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 1935293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1936293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1937293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 1938293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 1939293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 1940293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1941293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1942293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1943293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 1944293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 1945293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 1946293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 1947293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1948293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1949293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 1950293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1951293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 1952293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 1953293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 1954293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1955293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1956293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1957293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1958293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1959293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1960293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1961293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1962293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1963293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 1964293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 1965293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 1966293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1967293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1968293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 1969293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 1970293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 1971293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1972293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1973293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1974293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 1975293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 1976293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 1977293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 1978293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1979293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1980293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 1981293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1982293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 1983293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1984293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 1985293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 1986293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 19877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 19887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 19897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 1990f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 1991f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 1992f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 19937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 19947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 19957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 19967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 19977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 19987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 19997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 200016578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 20017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 20027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 20037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 20047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 20057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 20067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 200716578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 20087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 20097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 20107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 20117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 20127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 20137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 20147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 20157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 20167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 20177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 20187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 20197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2020f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2021f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 20220d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 20230d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 20240d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 20250d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 20260d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2027f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2028f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2029f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 20307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 20317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 20327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 20337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2034251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2035251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2036251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2037251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2038251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2039251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2040251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2041251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2042251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2043251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2044251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2045251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2046251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2047251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2048251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2049251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2050251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2051251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2052251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2053251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2054251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2055251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2056251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2057251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2058251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2059251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2060251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2061251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2062251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2063251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2064251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2065251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2066251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2067251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2068251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2069251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2070251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2071251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2072251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2073251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2074251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2075251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2076251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2077251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2078251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2079251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2080251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2081251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2082251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2083251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2084251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2085251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2086251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2087251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2088251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2089251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2090251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2091251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2092251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2093251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2094251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2095251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2096251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2097251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2098251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2099251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 2100251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2101251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2102251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 2103251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 21041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2105ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2106ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2107ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 21081355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2109ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2110ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2111ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2112ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2113ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2114ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 21157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2116ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2117ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2119ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2120548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2121548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2122548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2123548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 2124548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2125548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2126548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 2127548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2128548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2129548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2130548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2131548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 2132548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 2133548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 21341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2135ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2136ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2137ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 21381355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2139ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2140ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2141ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2142548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2143548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2144548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 21457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 21467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 21477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21487b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 21497b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 21507b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 21517b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 21527b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 21537b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 21547b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 21557b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 21567b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 21577b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 21587b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 21597b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 21607b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 21617b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 21627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 21637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 21647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 21657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 21667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 21677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 21687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2169ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 21707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 21717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 21727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 21737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 21747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 21757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 21767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2177ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2178ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2179ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2180ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 21817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2182ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2183ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2184ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 21857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 21867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 21877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2188aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2189ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2190ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 21917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 21927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 21937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 21947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 21957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 21967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 21977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 21987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 2199aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 22007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 22017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 22037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 22047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 22057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 22077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 22097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 22147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2215ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2216ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2217ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2218ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 22197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2220ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2221ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2222ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 22237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 22247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2225ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2226ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 22277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2228ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 22337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2234ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2235ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2236ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2237ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 22382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 22392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 22412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 22422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 22432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 22452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 22472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 22482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 22502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 22512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 22522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 22532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 22542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 22552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 225614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 225714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 225814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 225914605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 226014605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 226114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 226214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 226314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 226414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 226514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 226614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 226714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 226814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 226914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 227014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 227114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 227214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 227314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 2274623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2275623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2276623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2277623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 2278623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2279623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2280623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2281623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 2282623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2283623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2284623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2285623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 2286623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 2287623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2288623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2289e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 22909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 229150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 22927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2293762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 229418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 2295a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 2296762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2297b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 2298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 229918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 23001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 23017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 23027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 2303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 23040571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 23050571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 23060571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 23077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 23080571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 23097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 2310762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 2311b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 2312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 23137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 23147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, false, S, E)); 231503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 23167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 23177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 231850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 23197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 23207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 232150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 23227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If we have a '#' it's an immediate offset, else assume it's a register 23237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 23247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 23257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 23267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 232750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 23287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // FIXME: Special case #-0 so we can correctly set the U bit. 2329e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 23307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 23317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 23327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 233305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 23347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 23357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 23367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 23377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 23387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 23397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 23407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 23417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 23427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 23437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 23447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 23457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 234605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 23477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 23487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 23497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 23507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::no_shift, 0, false, S,E)); 2351a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 23527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 23537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 23547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 23557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 23567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 2357762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 23587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 23597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 23609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 2361d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 23627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 23637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 23647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 23657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 23667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 23677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 23687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 23697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 23707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 23719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 23727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 23737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 23747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 23757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 23767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 23777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 23787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 23790d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 23807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 23817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 23820d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 23837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 23849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 238516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 23867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 23877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 23887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 23897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 23907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 23917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 23927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 23930d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach ShiftType, ShiftImm, isNegative, 23947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 23957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2396f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 2397f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 2398f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 2399f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2400f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 2401f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 24029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 24039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 24049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 24059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 24067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 2407a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 2408a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 24097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 24107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 24117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 24127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 241318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2414a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2415a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 241638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 2417a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 24180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 2419a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 24200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 2421a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 24220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 2423a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 24240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 2425a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 24260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 2427a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 24287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 2429b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 2430a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 24327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 24337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 24347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 24357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 24367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 24377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 24387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 24397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 24409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 24417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 24427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 24437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 24447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 24457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 24467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 24477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 24487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 24497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 24507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 24517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 24527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 24537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 24547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 24557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 24567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 2457a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2458a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 2459a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 24629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 24631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2464fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 2465762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 2466fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2467fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 2468fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 2469f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2470f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 2471fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 2472f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 2473f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 2474f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 2475f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 2476f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 2477fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2478a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 2479146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 2480146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 248150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 248219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 24831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 248450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 24850d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 248619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 24870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 248819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 248919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 2490e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2491e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 2492e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 249319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 249467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 249567b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 2496515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 2497515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 2498515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 2499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2500515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 250150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2502762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 250350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 250450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 250550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 2506a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 25071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 2508d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 25091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 2510d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 2511079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 2512079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2513762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2514b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2515515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 2516515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 251750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2518762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 251950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 252050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 25219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 25229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 25237597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 25247597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 25257597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 25261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 25279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25297597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 25307597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 25319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25337597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 25347597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 25359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 25367597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 25379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 25389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 2539a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2540a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 25421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 25437597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 25441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 25457597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 25469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 25488a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 25499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 25509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 25529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 25539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 25559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 25579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 25587597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 25599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 25607597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 25619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 25629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 25639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 25659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 25669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 25689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 25699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 25719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 25729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 25739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 25749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 25761355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E, 25779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 25789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 25799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 25809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 25819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 25829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 25849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 25859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 25869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 25879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 25889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 25909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 25919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 25939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 25949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 25969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 25979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 25999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 26009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 26029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 26031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant); 26049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 26059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 26069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 26079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 26099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 26109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 26119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 26139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 26149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 26159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 2616352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 2617352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 2618352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 2619badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 26201355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 26215f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 26225f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 26235f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &ProcessorIMod) { 2624352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 2625352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 2626a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 2627352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2628badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 2629352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 2630352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 26315f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 26325f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 26335f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 26345f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 26355f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 26365f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 26375f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 26385f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2639352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2640badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 26413f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 26423f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 2643ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 264471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 264549f2ceddd25c75373f8a39fa25e8b9db33bcdaccJim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls") { 26463f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 26473f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 26483f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 26493f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 26503f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 26513f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 26523f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 26533f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 26543f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 26553f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 26563f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 26573f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 26583f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 26593f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 26603f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 26613f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 26623f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 26633f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 26643f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 26653f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 26663f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 26673f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 26683f00e317064560ad11168d22030416d853829f6eJim Grosbach } 266952925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 2670345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2671352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 2672352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 2673352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 2674352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 26755f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 26765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 26775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 2678e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 2679e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 2680352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2681352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 2682352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 2683352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2684a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 2685a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 2686a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 2687a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 2688a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 2689a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2690a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 2691a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 2692a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2693a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 2694a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2695a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 2696a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2697a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2698a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2699352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2700352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 27013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 27023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 27033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 27043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 27053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 2706fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 27071355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2708fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 2709eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2710eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2711eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2712eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2713be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2714eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2715eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 2716be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "eor" || Mnemonic == "smlal" || 2717ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 2718eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 2719eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 2720eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 2721eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 27223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 2723eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2724eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2725eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2726eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 27275f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2728c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Mnemonic == "setend" || 272948c693ff564c422153733424ab845106161430acJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) || 2730e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) 2731e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach && !isThumb()) || 27325f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 27333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 27343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 27353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 27363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 2737fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 2738ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 2739fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 274063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2741fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 2742badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 2743badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2744d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 2745d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2746d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 2747d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2748d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 2749d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 2750d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 2751d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 2752d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 2753d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 2754d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 2755d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (Mnemonic == "mov" && Operands.size() > 4 && 2756d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2757d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2758d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 2759d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 27603912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 27613912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 27623912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 27633912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 27643912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 27653912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 27663912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 27673912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 27683912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 2769d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 2770d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 2771d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 2772badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 2773badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2774badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2775badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 2776badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 2777ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 2778badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2779352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 2780352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 2781a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 2782352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 27831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2784c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach ProcessorIMod); 2785badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2786ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2787ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2788ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 2789ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 27909717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 27913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 27923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 27933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 27943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 27953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 27963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 27973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 27983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 27991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 28003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 280133c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 280233c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 280333c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 280433c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 2805ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 280633c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 280733c16a27370939de39679245c3dff72383c210bdJim Grosbach } 2808c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 2809c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 2810c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 2811c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 2812c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 2813c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 2814c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 281533c16a27370939de39679245c3dff72383c210bdJim Grosbach 28163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 28173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 28183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 28193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 28203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 282133c16a27370939de39679245c3dff72383c210bdJim Grosbach if (CanAcceptCarrySet) 28223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 28233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 28243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 28253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 28263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 28273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 28283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 2829badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 2830345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2831a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 2832a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 2833a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 2834a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 2835a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 2836a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 2837a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 2838a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 2839a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2840a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 2841a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2842a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2843345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 28445747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 28455747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 28465747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 2847a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 2848a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2849a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 28505747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 28515747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 28525747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 28535747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 2854a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 28551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 2856cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2857cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2858cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2859a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2860a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 2861b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 2862a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2863a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 28641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 2865cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2866cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2867cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2868a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2869a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 287016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2871cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2872cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 287334e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 2874cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2875146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 287634e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 2877ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2878d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 2879d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 2880d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 2881d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // parse and adjust accordingly before actually matching. Reason number 2882d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // #317 the table driven matcher doesn't fit well with the ARM instruction 2883d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // set. 2884d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (shouldOmitCCOutOperand(Mnemonic, Operands)) { 2885ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2886ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 2887ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 2888ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 2889ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2890cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 2891cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 2892cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 2893cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // a CondCode operand in the list. If we're trying to match the label 2894cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // version, remove the CondCode operand here. 2895cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 2896cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 2897cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2898cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 2899cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 2900cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 2901857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 2902857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 2903857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 2904857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 2905857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 2906857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 2907857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 2908857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 2909857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 2910857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 2911857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 2912857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 2913857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 2914857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 2915857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 29169898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 2917ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2918ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2919189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 2920189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 2921189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 2922189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 2923189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2924189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 29252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 29262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 29272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 2928189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 2929189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 2930189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 2931189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2932189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 2933189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 2934189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 2935189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2936189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 293714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 293814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 293914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 294014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 294114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 294214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 294314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 294414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 294514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 294653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 294753642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 2948189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 2949189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 2950189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2951189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 2952189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 295314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 2954189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 2955189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2956189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 2957fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 2958fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 2959fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 2960fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 2961fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 2962fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 2963fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 2964fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 2965fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 2966189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 2967189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 2968189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2969189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 2970189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 2971f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 2972f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 2973f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2974f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 2975f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 2976f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 2977f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 2978f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 2979f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 2980f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 2981f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 2982f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 2983f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 2984f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 2985f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 2986f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 2987f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 2988f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 2989f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 2990f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 2991f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 2992f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 2993f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 2994f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 2995f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 2996f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 2997f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 2998f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 2999f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3000f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3001f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 3002f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 3003f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3004f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3005f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 3006f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 3007f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 3008f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3009f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 3010f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 301147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 301247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 301347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// API changes, though. Better way? 301447a0d52b69056250a1edaca8b28f705993094542Jim Grosbachnamespace llvm { 301547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachextern MCInstrDesc ARMInsts[]; 301647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 301747a0d52b69056250a1edaca8b28f705993094542Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 301847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return ARMInsts[Opcode]; 301947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 302047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 302147a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 302247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 302347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 302447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 302547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 302647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 302747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 302847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 302947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 303047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 303147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 303247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 303347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 303447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 303547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 303647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 303747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 303847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 303947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 304047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 304147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // FIXME: We don't yet do IT blocks, so just always consider it to be 304247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // that we aren't in one until we do. 304347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 304447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 304547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 304647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 304747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 304847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 3049fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 3050fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 3051fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3052fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 3053fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 3054fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 305519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 3056193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 3057193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 305819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 3059e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 3060189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 3061189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 3062189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (validateInstruction(Inst, Operands)) 3063189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 3064189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3065f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 3066f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 3067f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 3068f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 3069fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 3070fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 3071e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 3072e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 3073e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 3074e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 3075e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 3076e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 3077e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 3078e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 307916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3080e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 3081e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 3082e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 308316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3084e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 3085e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 3086e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 308747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 3088b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 3089b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 309047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 309147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 3092fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 309316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3094c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 3095146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 3096fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 3097fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 30981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 3099ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 3100ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 3101ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 31021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 3103515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 31041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 3105515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 31061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 3107515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 31081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 3109515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 31101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 3111ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3112ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3113ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 31141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 3115ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 31161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 3117ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 3118ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 3119ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 3120ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 3121ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3122ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3123aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 3124ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3125ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 3126ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 312716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3128ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 3129ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 3130ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 3131b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3132ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3133ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3134ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3135b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3136ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 3137ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3138ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 31391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 3140515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 31411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 3142515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3143515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3144b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3145515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3146515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 3147515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 3148515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3149515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3150515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3151515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 31521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 3153515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 31541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 31556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 31566469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 31576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 31586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 31596469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 31606469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 31616469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 31626469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 31636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 31646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 31656469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 31666469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 31676469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 31686469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3169515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3170515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3171b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3172515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 31736469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 31746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 31756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 31766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 31776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3178642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 3179642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 3180642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 3181515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3182515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3183515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 31841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 3185515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 31861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 318718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3188515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3189515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 319038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 319158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 3192b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 319358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 31949e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 3195515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3196515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 3197515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3198515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 319918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3200b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3201515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3202515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 3203515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3204515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3205515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3206515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 32071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 3208515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 32091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 321018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3211515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 3212515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 321318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 321458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 3215b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 321658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 3217b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3218515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3219515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 3220515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3221515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 322218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3223b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3224515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 322532869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 3226bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (!isThumb()) { 3227ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3228bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3229bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 323032869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 3231bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (isThumb()) { 3232ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3233bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 3234bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 3235eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 32362a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 3237515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3238515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3239515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 324090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 324190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 32429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 3243ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 324494b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 324594b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 324690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 3247ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 32483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 32490692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 32500692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 32513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 3252